Чтение онлайн

на главную

Жанры

Язык программирования C#9 и платформа .NET5
Шрифт:

Чтобы их увидеть, может потребоваться щелкнуть на кнопке Refresh (Обновить) в окне Solution Explorer, т.к. они не являются частью фактического проекта, а представляют собой артефакты построения.

Чтобы сделать процесс более осмысленным, элементам управления полезно назначить имена. Назначьте имена элементам управления

Button
и
Calendar
, как показано ниже:

<Button Name="ClickMe" Content="Button" HorizontalAlignment="Left"

Margin="10,10,0,0"

VerticalAlignment="Top" Width="75" Click="Button_Click">

// Для краткости разметка
не показана,

</Button>

<Calendar Name="MyCalendar" HorizontalAlignment="Left" Margin="10,41,0,0"

VerticalAlignment="Top"/>

Теперь повторно скомпилируйте решение (или проект) и обновите файлы в окне Solution Explorer. Если открыть файл

MainWindow.g.cs
в текстовом редакторе, то внутри обнаружится класс по имени
MainWindow
, который расширяет базовый класс
Window
. Имя данного класса является прямым результатом действия атрибута
х:Class
в начальном дескрипторе
<Window>
.

В классе

MainWindow
определена закрытая переменная-член типа
bool
(с именем
_contentLoaded
), которая не была напрямую представлена в разметке XAML. Указанный член данных используется для того, чтобы определить (и гарантировать) присваивание содержимого окна только один раз. Класс также содержит переменную-член типа
System.Windows.Controls.Button
по имени
ClickMe
. Имя элемента управления основано на значении атрибута
x:Name
в открывающем объявлении
<Button>
. В классе не будет присутствовать переменная для элемента управления
Calendar
. Причина в том, что утилита
msbuild.ехе
создает переменную для каждого именованного элемента управления в разметке XAML, который имеет связанный код в отделенном коде. Когда такого кода нет, потребность в переменной отпадает. Чтобы еще больше запутать ситуацию, если бы элементу управления
Button
не назначалось имя, то и для него не было бы предусмотрено переменной. Это часть магии WPF, которая связана с реализацией интерфейса
IComponentConnector
.

Сгенерированный компилятором класс также явно реализует интерфейс

IComponentConnector
из WPF, определенный в пространстве имен
System.Windows.Markup
. В интерфейсе
IComponentConnector
имеется единственный метод
Connect
, который реализован для подготовки каждого элемента управления, определенного в разметке, и обеспечения логики событий, как указано в исходном файле
MainWindow.xaml
. Можно заметить обработчик, настроенный для события щелчка на кнопке
ClickMe
. Перед завершением метода переменная-член
_contentLoaded
устанавливается в
true
. Вот как выглядит данный метод:

void System.Windows.Markup.IComponentConnector.Connect(int connectionId,

object target)

{

switch (connectionId)

{

case 1:

this.ClickMe = ((System.Windows.Controls.Button)(target));

#line 11 "..\..\MainWindow.xaml"

this.ClickMe.Click +=

new System.Windows.RoutedEventHandler(this.Button_Click);

#line default

#line hidden

return;

}

this._contentLoaded = true;

}

Чтобы

продемонстрировать влияние неименованных элементов управления на код, добавьте к календарю обработчик события
SelectedDatesChanged
. Перекомпилируйте приложение, обновите файлы и заново загрузите файл
MainWindow.g.cs
. Теперь в методе
Connect
присутствует следующий блок кода:

#line 20 "..\..\MainWindow.xaml"

this.MyCalendar.SelectedDatesChanged += new

System.EventHandler<System.Windows.Controls.SelectionChangedEventArgs>(

this.MyCalendar_OnSelectedDatesChanged);

Он сообщает инфраструктуре о том, что элементу управления в строке 20 файла XAML назначен обработчик события

SelectedDatesChanged
, как показано в предыдущем коде.

Наконец, класс

MainWindow
определяет и реализует метод по имени
InitializeComponent
. Вы могли бы ожидать, что данный метод содержит код, который настраивает внешний вид и поведение каждого элемента управления, устанавливая его разнообразные свойства (
Height
,
Width
,
Content
и т.д.). Однако это совсем не так! Как тогда элементы управления получают корректный пользовательский интерфейс? Логика в методе
InitializeComponent
выясняет местоположение встроенного в сборку ресурса, который именован идентично исходному файлу
*.xaml
:

public void InitializeComponent {

if (_contentLoaded) {

return;

}

_contentLoaded = true;

System.Uri resourceLocater =

new System.Uri("/WpfTesterApp;component/mainwindow.xaml",

System.UriKind.Relative);

#line 1 "..\..\MainWindow.xaml"

System.Windows.Application.LoadComponent(this, resourceLocater);

#line default

#line hidden

}

Здесь возникает вопрос: что собой представляет этот встроенный ресурс?

Роль BAML

Как и можно было предположить, формат BAML является компактным двоичным представлением исходных данных XAML. Файл

*.baml
встраивается в виде ресурса (через сгенерированный файл
*.g.resources
) в скомпилированную сборку. Ресурс BAML содержит все данные, необходимые для настройки внешнего вида и поведения виджетов пользовательского интерфейса (т.е. свойств вроде
Height
и
Width
).

Здесь важно понимать, что приложение WPF содержит внутри себя двоичное представление (BAML) разметки. Во время выполнения ресурс BAML извлекается из контейнера ресурсов и применяется для настройки внешнего вида и поведения всех окон и элементов управления.

Вдобавок запомните, что имена таких двоичных ресурсов идентичны именам написанных автономных файлов

*.xaml
. Тем не менее, отсюда вовсе не следует необходимость распространения файлов
*.xaml
вместе со скомпилированной программой WPF. Если только не строится приложение WPF, которое должно динамически загружать и анализировать файлы
*.xaml
во время выполнения, то поставлять исходную разметку никогда не придется.

Поделиться:
Популярные книги

Измена. Жизнь заново

Верди Алиса
1. Измены
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Жизнь заново

Газлайтер. Том 9

Володин Григорий
9. История Телепата
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Газлайтер. Том 9

Жребий некроманта 2

Решетов Евгений Валерьевич
2. Жребий некроманта
Фантастика:
боевая фантастика
6.87
рейтинг книги
Жребий некроманта 2

Безымянный раб

Зыков Виталий Валерьевич
1. Дорога домой
Фантастика:
фэнтези
9.31
рейтинг книги
Безымянный раб

Я тебя не отпускал

Рам Янка
2. Черкасовы-Ольховские
Любовные романы:
современные любовные романы
6.55
рейтинг книги
Я тебя не отпускал

Меняя маски

Метельский Николай Александрович
1. Унесенный ветром
Фантастика:
боевая фантастика
попаданцы
9.22
рейтинг книги
Меняя маски

СД. Том 15

Клеванский Кирилл Сергеевич
15. Сердце дракона
Фантастика:
героическая фантастика
боевая фантастика
6.14
рейтинг книги
СД. Том 15

Идеальный мир для Лекаря 10

Сапфир Олег
10. Лекарь
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 10

Третий

INDIGO
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
Третий

Идеальный мир для Социопата 6

Сапфир Олег
6. Социопат
Фантастика:
боевая фантастика
рпг
6.38
рейтинг книги
Идеальный мир для Социопата 6

Огни Аль-Тура. Завоеванная

Макушева Магда
4. Эйнар
Любовные романы:
любовно-фантастические романы
эро литература
5.00
рейтинг книги
Огни Аль-Тура. Завоеванная

Жена по ошибке

Ардова Алиса
Любовные романы:
любовно-фантастические романы
7.71
рейтинг книги
Жена по ошибке

Я – Орк. Том 4

Лисицин Евгений
4. Я — Орк
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я – Орк. Том 4

Чехов. Книга 3

Гоблин (MeXXanik)
3. Адвокат Чехов
Фантастика:
альтернативная история
5.00
рейтинг книги
Чехов. Книга 3