понедельник, 5 апреля 2010 г.

Простой проект на WPF

Одно окошко — два файла

В Windows Forms проект состоит из набора форм. Каждая форма — это пара файлов: Form1.cs, Form1.Designer.cs. В Form1.Disigner.cs хранится код, созданный дизайнером форм, а в Form1.cs обработчки событий для элементов формы.
В WPF-проекте форма также хранится в двух файлах: Window1.xaml, Window1.xaml.cs. Window1.xaml создается дизайнером WPF, а в Window1.xaml.cs можем поместить cs код, относящийся к формочке. Формочки в WPF называются окнами. Поэтому в названии файла фигурирует слово 'Window'.
Обратим внимание на Window1.xaml. Это xml файл, который перед компиляцией транслируется в cs код. Почему же сразу не писать на cs? Писать можно, но дизайнер генерирует код в xaml-формате. Без дизайнера никак, иначе визуальное программирование превратится в программирование в notepad. Чтож, пускай будет xml.
Хочу продемонстрировать, что xaml-код — это на самом деле cs-код.

Конвертация xaml в cs


Создадим WPF-проект (File→New→Project…→WPF Application). Будет создан проект, в котором 2 элемента App.xaml (приложение) и Window1.xaml (единственное окно). Если нажать плюсики, то увидим, оставшиеся 2 элемента: App.xaml.cs, Window1.xaml.cs. В дизайнере открываем Window1.xaml и на окошко кидаем Label с надписью «Hello WPF». Причесываем внешний вид и получаем:
  1.  
  2. <Window x:Class="WpfApplication4.Window1"
  3.    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  4.    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  5.    Title="Window1" Height="300" Width="300">
  6.     <Grid>
  7.         <Label Name="label1" FontSize="36" VerticalAlignment="Center" HorizontalAlignment="Center">Hello WPF</Label>
  8.     </Grid>
  9. </Window>
  10.  

Запускаем приложение и видим нашу формочку. Ага, оно работает!
Теперь идем в папку obj\Debug и обнаруживаем там файл Window1.g.cs. Это и есть cs-код, построенный по xaml.
  1.  
  2. public partial class Window1 : System.Windows.Window, System.Windows.Markup.IComponentConnector {
  3.     #line 6 "..\..\Window1.xaml"
  4.     internal System.Windows.Controls.Label label1;
  5.    
  6.     #line default
  7.     #line hidden
  8.    
  9.     private bool _contentLoaded;
  10.    
  11.     /// <summary>
  12.     /// InitializeComponent
  13.     /// </summary>
  14.     [System.Diagnostics.DebuggerNonUserCodeAttribute()]
  15.     public void InitializeComponent() {
  16.         if (_contentLoaded) {
  17.             return;
  18.         }
  19.         _contentLoaded = true;
  20.         System.Uri resourceLocater = new System.Uri("/WpfApplication4;component/window1.xaml", System.UriKind.Relative);
  21.        
  22.         #line 1 "..\..\Window1.xaml"
  23.         System.Windows.Application.LoadComponent(this, resourceLocater);
  24.        
  25.         #line default
  26.         #line hidden
  27.     }
  28.    
  29.     [System.Diagnostics.DebuggerNonUserCodeAttribute()]
  30.     [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
  31.     [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
  32.     void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
  33.             switch (connectionId)
  34.             {
  35.             case 1:
  36.             this.label1 = ((System.Windows.Controls.Label)(target));
  37.             return;
  38.             }
  39.             this._contentLoaded = true;
  40.     }
  41. }
  42.  

Если присмотреться повнимательнее, то окажется, что код не полный. Нет установки свойств Content, Windth, Height, FontSize и др. Оказывается, что вся инициализация свойств элементов делается в строчке:
  1.  
  2. System.Windows.Application.LoadComponent(this, resourceLocater);
  3.  
Если откроем файл Window1.baml, то обнаружим в нем значения наших свойств. Понять baml-файл достаточно трудно, поскольку он бинарный.
Но тем не менее, мы убедились что xaml — это всего лишь промежуточный код, который приводится к cs-коду.

Декомпиляция xaml

С помощью .NET Reflector можно просматривать cs-код из exe-файлов. Открыв в нем наш exe-файл обнаружим выше приведенный код из Window1.g.cs. Но ресурсы, хранимые в baml-файле отображены не будут. Если установим плагинчик BamlViewer, то можем увидеть исходный xaml-файл.

______________________
Текст подготовлен в Редакторе Блогов от © SoftCoder.ru

Комментариев нет:

Отправить комментарий