浅谈WPF之控件模板Control Template和数据模板Data Template

这篇具有很好参考价值的文章主要介绍了浅谈WPF之控件模板Control Template和数据模板Data Template。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

WPF不仅支持传统的Windows Forms编程的用户界面和用户体验设计,同时还推出了以模板为核心的新一代设计理念。在WPF中,通过引入模板,将数据和算法的“内容”和“形式”进行解耦。模板主要分为两大类:数据模板【Data Template】和控件模板【Control Template】

基本上,ControlTemplate描述如何显示控件,而DataTemplate描述如何显示数据

控件模板 Control Template


控件模板让我们可以定义控件的外观,改变控件的展现形式,通过Control Template实现。

1. 编辑默认模板

 选中控件--右键--编辑模板--编辑副本,打开创建Style资源对话框,如下所示:

浅谈WPF之控件模板Control Template和数据模板Data Template,WPF,WPF之控件模板,WPF数据模板

创建Style资源,输入资源名称,定义位置,默认为此文档【Window】,然后点击【确定】,创建资源。如下所示: 

浅谈WPF之控件模板Control Template和数据模板Data Template,WPF,WPF之控件模板,WPF数据模板

创建控件元素的默认资源,如下所示: 


<Window x:Class="WpfApp2.TwoWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp2"
        mc:Ignorable="d"
        Title="TwoWindow" Height="350" Width="800">
    <Window.Resources>
        <Style x:Key="FocusVisual">
            <Setter Property="Control.Template">
                <Setter.Value>
                    <ControlTemplate>
                        <Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
</Style>
        <SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD"/>
        <SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070"/>
        <SolidColorBrush x:Key="Button.MouseOver.Background" Color="#FFBEE6FD"/>
        <SolidColorBrush x:Key="Button.MouseOver.Border" Color="#FF3C7FB1"/>
        <SolidColorBrush x:Key="Button.Pressed.Background" Color="#FFC4E5F6"/>
        <SolidColorBrush x:Key="Button.Pressed.Border" Color="#FF2C628B"/>
        <SolidColorBrush x:Key="Button.Disabled.Background" Color="#FFF4F4F4"/>
        <SolidColorBrush x:Key="Button.Disabled.Border" Color="#FFADB2B5"/>
        <SolidColorBrush x:Key="Button.Disabled.Foreground" Color="#FF838383"/>
        <Style x:Key="OneButtonStyle" TargetType="{x:Type Button}">
            <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
            <Setter Property="Background" Value="{StaticResource Button.Static.Background}"/>
            <Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}"/>
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="HorizontalContentAlignment" Value="Center"/>
            <Setter Property="VerticalContentAlignment" Value="Center"/>
            <Setter Property="Padding" Value="1"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
                            <ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsDefaulted" Value="true">
                                <Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                            </Trigger>
                            <Trigger Property="IsMouseOver" Value="true">
                                <Setter Property="Background" TargetName="border" Value="{StaticResource Button.MouseOver.Background}"/>
                                <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border}"/>
                            </Trigger>
                            <Trigger Property="IsPressed" Value="true">
                                <Setter Property="Background" TargetName="border" Value="{StaticResource Button.Pressed.Background}"/>
                                <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Pressed.Border}"/>
                            </Trigger>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.Background}"/>
                                <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border}"/>
                                <Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground}"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
</Style>
    </Window.Resources>
    <Grid>
        <Button x:Name="one" Content="Hello wpf" Margin="5" Width="100" Height="30" Style="{DynamicResource OneButtonStyle}"></Button>
    </Grid>
</Window>

2. 修改默认样式

通过默认创建的控件模板Style,可以修改和重定义控件的显示内容,如:设置按钮显示圆角,和鼠标放上去为红色。

浅谈WPF之控件模板Control Template和数据模板Data Template,WPF,WPF之控件模板,WPF数据模板

 要实现以上功能,只需要修改两个地方即可,如下所示:

浅谈WPF之控件模板Control Template和数据模板Data Template,WPF,WPF之控件模板,WPF数据模板

3. 自定义控件模板

通过自定义模板,同样能达到修改控件样式的效果。

控件模板也是资源的一种,每一个控件模板都有一个唯一的key,在控件上通过Template进行绑定,如下所示:


<Window x:Class="WpfApp2.ThreeWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp2"
        mc:Ignorable="d"
        Title="自定义控件模板示例" Height="150" Width="300">
    <Window.Resources>
        <ControlTemplate x:Key="oneStyle" TargetType="Button">
            <Border Background="LightBlue" CornerRadius="5" x:Name="border">
                <StackPanel Orientation="Horizontal" HorizontalAlignment="{TemplateBinding HorizontalAlignment}">
                    <TextBlock VerticalAlignment="{TemplateBinding VerticalAlignment}">》》</TextBlock>
                    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}"></ContentPresenter>
                </StackPanel>
            </Border>
            <ControlTemplate.Triggers>
                <Trigger Property="IsMouseOver" Value="true">
                    <Setter Property="Background" TargetName="border" Value="Red"/>
                    <Setter Property="BorderBrush" TargetName="border" Value="Blue"/>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </Window.Resources>
    <Grid>
        <Button x:Name="one" Content="Hello wpf" Margin="5" Width="100" Height="30" VerticalAlignment="Center"  HorizontalAlignment="Center" Template="{StaticResource oneStyle}"></Button>
    </Grid>
</Window>

 自定义控件模板,示例如下:

浅谈WPF之控件模板Control Template和数据模板Data Template,WPF,WPF之控件模板,WPF数据模板

数据模板 DataTemplate 

控件模板决定了数据的展示形式和用户体检,在软件UI设计中非常重要。同样数据的展示形式越来越多样化,正所谓:横看成岭侧成峰,远近高低各不同。同样的数据内容,在DataGrid中的展示是文本的列表形式,在ComboBox中是下拉框的形式。给数据披上外衣,将数据和形式解耦,是一种新的发展趋势。

1. DataGrid

a. 数据模板

DataGrid是可以自定义网格数据显示的控件,通过自定义显示的列模板,可以实现各式各样的展现方式。列定义如下:

  1. DataGrid的列定义,通过Binding="{Binding Name}"的方式绑定属性,通过ElementStyle="{StaticResource one_center}"的方式绑定样式。

  2. DataGrid预制了几种列展示数据的方式,如:DataGridTextColumn【文本】,DataGridCheckBoxColumn【复选框】,DataGridComboBoxColumn【下拉框】,DataGridHyperlinkColumn【链接】等,如果使用数据模板,则采用DataGridTemplateColumn进行定义。

UI示例如下所示:

<Window x:Class="WpfApp2.A1Window"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp2"
        mc:Ignorable="d"
        Title="数据模板示例" Height="450" Width="650">
    <Window.Resources>
        <Style x:Key="one_center" TargetType="TextBlock">
            <Setter Property="VerticalAlignment" Value="Center"></Setter>
            <Setter Property="HorizontalAlignment" Value="Center"></Setter>
</Style>
        <Style x:Key="one_header" TargetType="DataGridColumnHeader">
            <Setter Property="VerticalAlignment" Value="Center"></Setter>
            <Setter Property="HorizontalAlignment" Value="Center"></Setter>
            <Setter Property="HorizontalContentAlignment" Value="Center"></Setter>
            <Setter Property="BorderThickness" Value="0"></Setter>
</Style>
    </Window.Resources>
    <Grid>
        <DataGrid x:Name="one"  Margin="10" AutoGenerateColumns="False"  CanUserAddRows="False"  CanUserSortColumns="False" BorderThickness="0" >
            <DataGrid.Columns>
                <DataGridTextColumn Header="姓名" Binding="{Binding Name}" Width="*" ElementStyle="{StaticResource one_center}" HeaderStyle="{StaticResource one_header}"  />
                <DataGridTextColumn Header="年龄" Binding="{Binding Age}" Width="*" ElementStyle="{StaticResource one_center}" HeaderStyle="{StaticResource one_header}"/>
                <DataGridTextColumn Header="性别" Binding="{Binding Sex}" Width="*" ElementStyle="{StaticResource one_center}" HeaderStyle="{StaticResource one_header}"/>
                <DataGridTextColumn Header="班级" Binding="{Binding Classes}" Width="*" ElementStyle="{StaticResource one_center}" HeaderStyle="{StaticResource one_header}"/>
                <DataGridTemplateColumn Header="操作" Width="*" HeaderStyle="{StaticResource one_header}">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
                                <Button x:Name="edit" Content="编辑" Width="60" Margin="3" Height="25"></Button>
                                <Button x:Name="delete" Content="删除" Width="60" Margin="3" Height="25"></Button>
                            </StackPanel>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

b. 后台数据绑定

后台数据绑定通过ItemsSource进行赋值,绑定的数据的属性名,要和DataGrid的列绑定数据的名称保持一致,如下所示:

namespace WpfApp2
{
    /// <summary>
    /// A1Window.xaml 的交互逻辑
    /// </summary>
    public partial class A1Window : Window
    {
        public A1Window()
        {
            InitializeComponent();

            List<Student> lst = new List<Student>();
            lst.Add(new Student() { Name = "张三", Age = 22, Sex = "男", Classes = "一班" });
            lst.Add(new Student() { Name = "李四", Age = 21, Sex = "男", Classes = "二班" });
            lst.Add(new Student() { Name = "王五", Age = 20, Sex = "女", Classes = "一班" });
            lst.Add(new Student() { Name = "刘大", Age = 19, Sex = "男", Classes = "三班" });
            lst.Add(new Student() { Name = "麻子", Age = 18, Sex = "男", Classes = "四班" });
            one.ItemsSource = lst;
        }
    }


    public class Student
    {
        public string Name { get; set; }

        public int Age { get; set; }

        public string Sex { get; set; }

        public string Classes { get; set; }
    }
}

 DataGrid示例,如下所示:

浅谈WPF之控件模板Control Template和数据模板Data Template,WPF,WPF之控件模板,WPF数据模板

2. ListBox和ComboBox

a. 数据模板

ListBox,ComboBox,均是包含可选择的项的列表,只是ListBox不需要下拉显示,ComboBox需要下拉显示。通过定义数据模板,可以丰富数据的展示形式。

通过ItemTemplate="{StaticResource item_template}"的形式,进行数据模板的绑定。如下所示:

<Window x:Class="WpfApp2.A2Window"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp2"
        mc:Ignorable="d"
        Title="数据模板示例" Height="450" Width="800">
    <Window.Resources>
        <DataTemplate x:Key="item_template">
            <StackPanel Orientation="Horizontal" Margin="5 ,0">
                <Border Width="10" Height="10" Background="{Binding Code}"></Border>
                <TextBlock Text="{Binding Code}" Margin="5,0" ></TextBlock>
            </StackPanel>
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <StackPanel Margin="3" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
            <ComboBox x:Name="one" Height="25" Width="120" Margin="5" ItemTemplate="{StaticResource item_template}"></ComboBox>
            <ListBox x:Name="two"  Width="120" Margin="5" ItemTemplate="{StaticResource item_template}"></ListBox>
        </StackPanel>
    </Grid>
</Window>

b. 后台数据绑定

与DataGrid一样,后台通过ItemsSource进行数据的绑定。如下所示:


namespace WpfApp2
{
    /// <summary>
    /// A2Window.xaml 的交互逻辑
    /// </summary>
    public partial class A2Window : Window
    {
        public A2Window()
        {
            InitializeComponent();
            List<Color> lst = new List<Color>();
            lst.Add(new Color() { Code = "#FE8C00" });
            lst.Add(new Color() { Code = "#1F7F50" });
            lst.Add(new Color() { Code = "#AA8C00" });
            lst.Add(new Color() { Code = "#FEAA00" });
            lst.Add(new Color() { Code = "#008CAA" });
            lst.Add(new Color() { Code = "#FEBB00" });
            one.ItemsSource = lst;
            two.ItemsSource = lst;
        }
    }

    public class Color
    {
        public string Code { get; set; }
    }
}

 浅谈WPF之控件模板Control Template和数据模板Data Template,WPF,WPF之控件模板,WPF数据模板

3. ItemsControl

a. 数据模板

ItemsControl,主要用于展示集合数据的项,也是列表控件的一种。ItemsControl 需要设置两个内容:

  • ItemsControl.ItemsPanel,做为数据展示的容器。

  • ItemsControl.ItemTemplate,用于单个数据的展示形式。

具体如下所示:

<Window x:Class="WpfApp2.A3Window"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp2"
        mc:Ignorable="d"
        Title="A3Window" Height="450" Width="800">
    <Grid>
        <ItemsControl x:Name="one">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel></WrapPanel>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Button Width="50" Height="50" Margin="5" Content="{Binding Code}"></Button>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>
</Window>

b. 后台数据绑定

与DataGrid一样,后台通过ItemsSource进行数据的绑定。如下所示:


namespace WpfApp2
{
    /// <summary>
    /// A3Window.xaml 的交互逻辑
    /// </summary>
    public partial class A3Window : Window
    {
        public A3Window()
        {
            InitializeComponent();
            List<Test> lst = new List<Test>();
            lst.Add(new Test() { Code = "1" });
            lst.Add(new Test() { Code = "2" });
            lst.Add(new Test() { Code = "3" });
            lst.Add(new Test() { Code = "4" });
            lst.Add(new Test() { Code = "5" });
            lst.Add(new Test() { Code = "6" });
            one.ItemsSource = lst;
        }
    }

    public class Test
    {
        public string Code { get; set; }
    }
}

 浅谈WPF之控件模板Control Template和数据模板Data Template,WPF,WPF之控件模板,WPF数据模板文章来源地址https://www.toymoban.com/news/detail-769582.html

到了这里,关于浅谈WPF之控件模板Control Template和数据模板Data Template的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 浅谈WPF之控件拖拽与拖动

    使用过office的visio软件画图的小伙伴都知道,画图软件分为两部分,左侧图形库,存放各种图标,右侧是一个画布,将左侧图形库的图标控件拖拽到右侧画布,就会生成一个新的控件,并且可以自由拖动。那如何在WPF程序中,实现类似的功能呢?今天就以一个简单的小例子,

    2024年02月05日
    浏览(60)
  • WPF控件模板2

    在控件模板和为其提供支持的代码之间有一个隐含约定。如果使用自定义控件模板替代控件的标准模板,就需要确保新模板能够满足控件的实现代码的所有需要。 在简单控件中,这个过程就比较容易,因为对模板几乎没有(或者完全没有)什么真正的要求。对于复杂控件,问

    2024年02月07日
    浏览(53)
  • WPF 自定义DataGrid控件样式模板5个

    样式一: 样式代码: 初始化绑定数据C#代码: 效果展示: 样式二: 上面的代码实现了隔行换色的效果,但是没有鼠标选中效果。另外有些用户希望能够进行列头拖动及排序。那么就需要做以下更改: 添加DataGridRow样式: 在引用时,设置DataGrid的RowStyle=\\\"{StaticResource AlertCoun

    2023年04月27日
    浏览(46)
  • 【.NET深呼吸】用代码写WPF控件模板

    这一次咱们来探究一下怎么用纯代码写 WPF 模板。模板有个共同基类 FrameworkTemplate,数据模板、控件模板等是从此类派生的,因此,该类已定义了一些通用成员。 用代码构建模板,重要的成员是 VisualTree 属性,它的类型是 FrameworkElementFactory。可见,模板不是直接创建可视化

    2024年02月09日
    浏览(42)
  • 【WPF】获取父控件数据

    https://www.cnblogs.com/-Timosthetic/p/16021865.html

    2024年02月20日
    浏览(34)
  • WPF数据模板

    样式提供了基本的格式化能力,但它们不能消除到目前为止看到的列表的最重要的局限性:不管如何修改ListBoxItem,它都只是ListBoxItem,而不是功能更强大的元素组合。并且因为每个ListBoxItem只支持单个绑定字段,所以不可能实现包含多个字段或图像的富列表。 然而WPF另有一个

    2024年02月10日
    浏览(40)
  • WPF4 数据模板

    数据模板常用在3种类型的控件, 下图形式: 1.Grid这种列表表格中修改Cell的数据格式, CellTemplate可以修改单元格的展示数据的方式。 2.针对列表类型的控件, 例如树形控件,下拉列表,列表控件, 可以修改其中的ItemTemplate。 3.修改ContentTemplate, 例UserControl控件的数据展现形式。 定

    2024年04月25日
    浏览(26)
  • c# wpf Template ContentTemplate

    1.概要 1.1 定义内容的外观 2.2 要点分析 2.代码 3.运行结果

    2024年04月09日
    浏览(40)
  • WPF基础入门-Class3-WPF数据模板

    Class3:WPF数据模板 1、先在cs文件中定义一些数据 2、xaml中编写模板 3、效果:

    2024年02月11日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包