Если вырвешь волосы их не вернешь назад
Как я писал в предыдущем посте проект впф состоит из файлов 2-х видов: xml-файл с описанием интерфейса и cs-файл с исполняемым кодом. В проекте cs-файл вложен в xaml-файл. Но на жестком диске эти файлы лежат отдельно. Так вот, связи между файлами не определяются динамически, а прописаны в csproj-файле в таком вот виде:
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Page Include="Window1.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Compile Include="Window1.xaml.cs">
<DependentUpon>Window1.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup>
Если случайно выкинуть из проекта один из файлов, то чтоб его добавить обратно придется поредактировать в блокноте csproj-файл. Из студии добавить опцию DependentUpon не представляется возможным.
Необработанные исключения
Некрасиво когда приложение завершается с сообщением: «Я совершил недопустимую операцию и закрыт операционной системой». Обработчики в каждый метод лениво ставить. Выход есть, в app.xaml прописываем:
<Application x:Class="ADODataSet2.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
DispatcherUnhandledException="HandleException"
StartupUri="Window1.xaml">
</Application>
А в файл app.xaml.cs добавляем код обработчика:
private void HandleException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
MessageBox.Show(e.Exception.ToString(), "Что-то случилось");
}
Впф-матрешка
Как меня учил незабвенный Вася: «Основная фишка впф – это то, что внутри любого контрола может находиться другой контрол». Например, внутри чекбокса может быть кнопка, внутри кнопки список и т.д. Можно наваять городок в табакерке.Но описывать весь пользовательский интерфейс одним xaml-файлом неудобно. Хочется разбить описание на несколько файлов. Если окно содержит панели, то содержимое панелей можно вынести в отдельные xaml-файлы. Вот как может выглядеть содержимое Window1.xaml (главное окно программы):
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:WpfApplication1"
Title="Window1" Height="300" Width="300">
<StackPanel>
<c:UserControl1/>
<c:UserControl2/>
</StackPanel>
</Window>
UserControl1 и UserControl2 – это пользовательские контролы, которые мы создали нажав правую кнопку мыши на проекте и выбрав пункт Add->User Control… Вот что студия сгенерила:
UserControl.xaml:
<UserControl x:Class="WpfApplication1.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<Grid>
</Grid>
</UserControl>
UserControl.xaml.cs:
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for UserControl1.xaml
/// </summary>
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
}
}
Можем накидать в промежуток между <Grid> … </Grid> то, что нам нужно. Можно даже сделать класс наследником не UserControl, а другого класса, например, Button. Для этого слово ‘UserControl’ в xaml- и cs-файлах меняем на ‘Button’. Получится пользовательская кнопка.