zl程序教程

您现在的位置是:首页 >  后端

当前栏目

WPF模板语法

WPF模板 语法
2023-09-14 09:16:29 时间

WPF中的三大模板

  • ControlTemplate
  • ItemsPanelTemplate
  • DataTemplate

ControlTemplateItemsPanelTemplate 是控件模板
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 具有一个类型为 ItemsPanelTemplatePanel 属性。 ItemsControl 类型具有一个类型为 ItemsPanelTemplateItemsPanel 属性。

<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,它专门对 TreeViewItemMenuItem 的一些数据对象的绑定。