Язык программирования C#9 и платформа .NET5
<ControlTemplate x:Key="RoundButtonTemplate" TargetType="Button" ><Grid x:Name="controlLayout"><Ellipse x:Name="buttonSurface" Fill="LightBlue" /><Label x:Name="buttonCaption" Content="OK!"FontSize="20" FontWeight="Bold"HorizontalAlignment="Center"VerticalAlignment="Center" /></Grid><ControlTemplate.Triggers><Trigger Property="IsMouseOver" Value="True"><Setter TargetName="buttonSurface" Property="Fill"Value="Blue"/><Setter TargetName="buttonCaption"Property="Foreground" Value="Yellow"/></Trigger><Trigger Property="IsPressed" Value="True"><Setter TargetName="controlLayout"Property="RenderTransformOrigin" Value="0.5,0.5"/><Setter TargetName="controlLayout"Property="RenderTransform"><Setter.Value><ScaleTransform ScaleX="0.8" ScaleY="0.8"/></Setter.Value></Setter></Trigger></ControlTemplate.Triggers></ControlTemplate>Роль расширения разметки {TemplateBinding}
Проблема с шаблоном элемента управления связана с тем, что каждая кнопка выглядит и содержит тот же самый текст. Следующее обновление разметки не оказывает никакого влияния:
<Button x:Name="myButton" Width="100" Height="100"Background="Red" Content="Howdy!" Click="myButton_Click"Template="{StaticResource RoundButtonTemplate}" /><Button x:Name="myButton2" Width="100" Height="100"Background="LightGreen" Content="Cancel!"Template="{StaticResource RoundButtonTemplate}" /><Button x:Name="myButton3" Width="100" Height="100"Background="Yellow" Content="Format"Template="{StaticResource RoundButtonTemplate}" />Причина в том, что стандартные свойства элемента управления (такие как
иBackGround) переопределяются в шаблоне. Чтобы они стали доступными, их потребуется отобразить на связанные свойства в шаблоне. Решить такие проблемы можно за счет использования расширения разметкиContentпри построении шаблона. Оно позволяет захватывать настройки свойств, которые определены элементом управления, применяющим шаблон, и использовать их при установке значений в самом шаблоне.{TemplateBinding}Ниже приведена переделанная версия шаблона
, в которой расширение разметкиRoundButtonTemplateприменяется для отображения свойства{TemplateBinding}элементаBackgroundна свойствоButtonэлементаFill; здесь также обеспечивается действительная передача значенияEllipseэлементаContentсвойствуButtonэлементаContent:Label<Ellipse x:Name="buttonSurface" Fill="{TemplateBinding Background}"/><Label x:Name="buttonCaption" Content="{TemplateBinding Content}"FontSize="20" FontWeight="Bold" HorizontalAlignment="Center"VerticalAlignment="Center" />После такого обновления появляется возможность создания кнопок с разными цветами и текстом. Результат обновления разметки XAML представлен на рис.27.13.
Роль класса ContentPresenter
При проектировании шаблона для отображения текстового значения элемента управления использовался элемент
. ПодобноLabelон поддерживает свойствоButton. Следовательно, если применяется расширение разметкиContent, тогда можно определять элемент{TemplateBinding}со сложным содержимым, а не только с простой строкой.ButtonНо что, если необходимо передать сложное содержимое члену шаблона, который не имеет свойства
? Когда в шаблоне требуется определить обобщенную область отображения содержимого, то вместо элемента управления специфического типа (ContentилиLabel) можно использовать классTextBox. Хотя в рассматриваемом примере в этом нет нужды, ниже показана простая разметка, иллюстрирующая способ построения специального шаблона, который применяет классContentPresenterдля отображения значения свойстваContentPresenterэлемента управления, использующего шаблон:Content
