Одно окошко — два файла
В 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». Причесываем внешний вид и получаем:
-
- <Window x:Class="WpfApplication4.Window1"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- Title="Window1" Height="300" Width="300">
- <Grid>
- <Label Name="label1" FontSize="36" VerticalAlignment="Center" HorizontalAlignment="Center">Hello WPF</Label>
- </Grid>
- </Window>
-
Запускаем приложение и видим нашу формочку. Ага, оно работает!
Теперь идем в папку obj\Debug и обнаруживаем там файл Window1.g.cs. Это и есть cs-код, построенный по xaml.
-
- public partial class Window1 : System.Windows.Window, System.Windows.Markup.IComponentConnector {
- #line 6 "..\..\Window1.xaml"
- internal System.Windows.Controls.Label label1;
-
- #line default
- #line hidden
-
- private bool _contentLoaded;
-
- /// <summary>
- /// InitializeComponent
- /// </summary>
- [System.Diagnostics.DebuggerNonUserCodeAttribute()]
- public void InitializeComponent() {
- if (_contentLoaded) {
- return;
- }
- _contentLoaded = true;
- System.Uri resourceLocater = new System.Uri("/WpfApplication4;component/window1.xaml", System.UriKind.Relative);
-
- #line 1 "..\..\Window1.xaml"
- System.Windows.Application.LoadComponent(this, resourceLocater);
-
- #line default
- #line hidden
- }
-
- [System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
- void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
- switch (connectionId)
- {
- case 1:
- this.label1 = ((System.Windows.Controls.Label)(target));
- return;
- }
- this._contentLoaded = true;
- }
- }
-
Если присмотреться повнимательнее, то окажется, что код не полный. Нет установки свойств Content, Windth, Height, FontSize и др. Оказывается, что вся инициализация свойств элементов делается в строчке:
-
- System.Windows.Application.LoadComponent(this, resourceLocater);
-
Если откроем файл Window1.baml, то обнаружим в нем значения наших свойств. Понять baml-файл достаточно трудно, поскольку он бинарный.Но тем не менее, мы убедились что xaml — это всего лишь промежуточный код, который приводится к cs-коду.
Декомпиляция xaml
С помощью .NET Reflector можно просматривать cs-код из exe-файлов. Открыв в нем наш exe-файл обнаружим выше приведенный код из Window1.g.cs. Но ресурсы, хранимые в baml-файле отображены не будут. Если установим плагинчик BamlViewer, то можем увидеть исходный xaml-файл.______________________
Комментариев нет:
Отправить комментарий