Язык программирования C#9 и платформа .NET5
На заметку! Если нужно определить в разметке класс, который является частью текущей сборки, но находится в другом пространстве имен .NET Core, то префикс дескриптора
определяется без атрибутаxmlnsassembly=:xmlns:myCtrls="clr-namespace:SomeNamespacelnMyApp"Управление видимостью классов и переменных-членов
Многие ключевые слова вы увидите в действии в последующих главах там, где они потребуются; тем не менее, в качестве простого примера взгляните на следующее XAML-определение
, в котором применяются ключевые слова<Window>иClassModifier, а такжеFieldModifierиx:Name(вспомните, что редактор Kaxaml не позволяет использовать ключевые слова XAML, вовлекающие компиляцию, такие какх:Class,x:Codeилих:FieldModifier):х:ClassModifier<b><!-- Этот класс теперь будет объявлен как internal в файле *.g.cs —> </b><Window x:Class="MyWPFApp.MainWindow" x:ClassModifier ="internal"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"><b> <!-- Эта кнопка будет объявлена как public в файле *.g.cs --></b><Button x:Name ="myButton" x:FieldModifier ="public" Content = "OK"/></Window>По умолчанию все определения типов C#/XAML являются открытыми (
), а члены — внутренними (public). Однако для показанного выше определения XAML результирующий автоматически сгенерированный файл содержит внутренний тип класса с открытой переменной-членомinternal:Button<b>internal</b> partial class MainWindow : System.Windows.Window,System.Windows.Markup.IComponentConnector{<b>public</b> System.Windows.Controls.Button myButton;...}Элементы XAML, атрибуты XAML и преобразователи типов
После установки корневого элемента и необходимых пространств имен XML следующая задача заключается в наполнении корня дочерним элементом. В реальном приложении WPF дочерним элементом будет диспетчер компоновки (такой как
илиGrid), который в свою очередь содержит любое количество дополнительных элементов, описывающих пользовательский интерфейс. Такие диспетчеры компоновки рассматриваются в главе 25, а пока предположим, что элементStackPanelбудет содержать единственный элемент<Window>.ButtonКак было показано ранее в главе, элементы XAML отображаются на типы классов или структур внутри заданного пространства имен .NET Core, тогда как атрибуты в открывающем дескрипторе элемента отображаются на свойства или события конкретного типа. В целях иллюстрации введите в редакторе Kaxaml следующее определение
:<Button><Pagexmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"><Grid><!-- Сконфигурировать внешний вид элемента Button --><Button Height="50" Width="100" Content="OK!"FontSize="20" Background="Green" Foreground="Yellow"/></Grid></Page>Обратите внимание, что присвоенные свойствам значения представлены с помощью простого текста. Это может выглядеть как полное несоответствие типам данных, поскольку после создания такого элемента
в коде C# данным свойствам будут присваиваться не строковые объекты, а значения специфических типов данных. Например, ниже показано, как та же самая кнопка описана в коде:Buttonpublic void MakeAButton(){Button myBtn = new Button();myBtn.Height = 50;myBtn.Width = 100;myBtn.FontSize = 20;myBtn.Content = "OK!";myBtn.Background = new SolidColorBrush(Colors.Green);myBtn.Foreground = new SolidColorBrush(Colors.Yellow);}Оказывается, что инфраструктура WPF поставляется с несколькими классами преобразователей типов, которые будут применяться для трансформации простых текстовых значений в корректные типы данных. Такой процесс происходит прозрачно (и автоматически).
Тем не менее, нередко возникает потребность в присваивании атрибуту XAML намного более сложного значения, которое невозможно выразить посредством простой строки. Например, пусть необходимо построить специальную кисть для установки свойства
элементаBackground. Создать кисть подобного рода в коде довольно просто:Buttonpublic void MakeAButton(){...// Необычная кисть для фона.LinearGradientBrush fancyBruch =new LinearGradientBrush(Colors.DarkGreen, Colors.LightGreen, 45);myBtn.Background = fancyBruch;