WPF模板语法
2023-09-14 09:16:29 时间
WPF模板语法
WPF中的三大模板
- ControlTemplate
- ItemsPanelTemplate
- DataTemplate
ControlTemplate
和ItemsPanelTemplate
是控件模板
DataTemplate
是数据模板
ControlTemplate
ControlTemplate:控件模板主要有两个重要属性:
VisualTree
内容属性和Triggers
触发器。所谓VisualTree
(视觉树),就是呈现我们所画的控件。
Triggers
可以对我们的视觉树上的元素进行一些变化。一般用于单内容控件。
<Window.Resources>
<Style TargetType="{x:Type Button}" x:Key="ButtonStyle">
<Setter Property="Content" Value="Hello World"/>
<Setter Property="Width" Value="200"/>
<Setter Property="Height" Value="200"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Border Background="{TemplateBinding Background}" BorderThickness="0" CornerRadius="100"/>
<Ellipse Width="200" Height="200" Name="Ellipse">
<Ellipse.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="Blue"/>
<GradientStop Offset="1" Color="LightBlue"/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Ellipse Width="160" Height="160">
<Ellipse.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="White"/>
<GradientStop Offset="1" Color="Transparent"/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center" Content="{TemplateBinding Content}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Hand"/>
<Setter TargetName="Ellipse" Property="Fill">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="Green"/>
<GradientStop Offset="1" Color="LightGreen"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Content" Value="Hello WPF"/>
</Trigger>
<Trigger Property="IsFocused" Value="True">
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Button Style="{StaticResource ButtonStyle}"/>
</Grid>
这里用到了
ControlPresenter
为什么没有使用ContentControl
呢
主要原因使二者的实现不同,不同情况下会有不同的性能表现
ContentControl
继承于Control
的 官方解释为:表示包含 单项内容的控件、ContentControl
可以包含任何类型的公共语言运行库对象。
ContentPresenter
继承于FrameworkElement
通常叫做 内容占位符。
在模板当中建议使用ContentPresenter
其外视情况而定。
ItemsPanelTemplate
官方解释:ItemsPanelTemplate
指定用于项的布局的面板。 GroupStyle
具有一个类型为 ItemsPanelTemplate
的 Panel
属性。 ItemsControl
类型具有一个类型为 ItemsPanelTemplate
的 ItemsPanel
属性。
<Window.Resources>
<Style TargetType="{x:Type ListBox}" x:Key="ListBoxStyle">
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel>
<Image Source="{Binding UriSource}" Width="150"/>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
<!--布局可以随着窗体宽度变化-->
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
</Style>
</Window.Resources>
<Grid>
<ListBox x:Name="listBox" Style="{StaticResource ListBoxStyle}"/>
</Grid>
后台代码
public MainWindow()
{
InitializeComponent()
listBox.ItemsSource = ListImages();
}
private List<BitmapImage> ListImages()
{
List<BitmapImage> bitmapImages = new List<BitmapImage>();
DirectoryInfo directoryInfo = new DirectoryInfo(@".\Imgages");
foreach (FileInfo item in directoryInfo.GetFiles("*.jpg"))
{
Uri uri = new Uri(item.FullName);
bitmapImages.Add(new BitmapImage(uri));
}
return bitmapImages;
}
ControlTemplate → ItemsPresenter 和 ContentPresenter
<Window.Resources>
<Style TargetType="TreeViewItem">
<Style.Resources>
<LinearGradientBrush x:Key="ItemAreaBrush" StartPoint="0,0.5" EndPoint="0.5,1">
<GradientStop Offset="0" Color="#66000000"/>
<GradientStop Offset="1" Color="#22000000"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="SelectedItemAreaBrush" StartPoint="0.5, 0" EndPoint="0.5, 1">
<GradientStop Color="Orange" Offset="0" />
<GradientStop Color="OrangeRed" Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ItemBorderBrush" StartPoint="0.5, 0" EndPoint="0.5, 1">
<GradientStop Color="LightGray" Offset="0" />
<GradientStop Color="Gray" Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="SelectedItemBorderBrush" StartPoint="0.5, 0" EndPoint="0. 5, 1">
<GradientStop Color="Yellow" Offset="0" />
<GradientStop Color="Black" Offset="1" />
</LinearGradientBrush>
<DropShadowBitmapEffect x:Key="DropShadowEffect"/>
</Style.Resources>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TreeViewItem">
<Grid Margin="2">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border x:Name="border" Background="{StaticResource ResourceKey=ItemAreaBrush}"
BorderBrush="{StaticResource ItemBorderBrush}" BorderThickness="1" CornerRadius="8" Padding="6">
<ContentPresenter ContentSource="Header" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Border>
<ItemsPresenter Grid.Row="1"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="border" Property="Panel.Background" Value="{StaticResource SelectedItemAreaBrush}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" IsItemsHost="True"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
<ResourceDictionary>
<HierarchicalDataTemplate DataType="{x:Type local:Node}" ItemsSource="{Binding ChildNodes}">
<TextBlock Text="{Binding Name}"/>
</HierarchicalDataTemplate>
</ResourceDictionary>
</Window.Resources>
<Grid>
<Grid Grid.Row="2">
<TreeView x:Name="treeView"/>
</Grid>
</Grid>
后台代码
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Loaded += MainWindow_Loaded;
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
treeView.PreviewKeyDown += (o, a) => { a.Handled = true; };
PopulateTreeView();
}
private void PopulateTreeView()
{
Node rootNode = new Node("GrandFather");
for (int i = 0; i < 2; i++)
{
Node child = new Node("Father");
rootNode.ChildNodes.Add(child);
for (int j = 0; j < 3; j++)
{
Node child2 = new Node("Son");
child.ChildNodes.Add(child2);
}
}
Node dummy = new Node();
dummy.ChildNodes.Add(rootNode);
treeView.ItemsSource = dummy.ChildNodes;
}
}
public class Node
{
private IList<Node> _childNodes;
public Node() { }
public Node(string name)
{
Name = name;
}
public string Name { get; set; }
public IList<Node> ChildNodes
{
get
{
if (_childNodes == null)
_childNodes = new List<Node>();
return _childNodes;
}
}
}
DataTemplate 和 HierarchicalDataTemplate
DataTemplate
就是显示绑定数据对象的模板。
HierarchicalDataTemplate
继承于DataTemplate
,它专门对TreeViewItem
或MenuItem
的一些数据对象的绑定。