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

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

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

控件模板 Control Template


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

1. 编辑默认模板

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

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

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


<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,可以修改和重定义控件的显示内容,如:设置按钮显示圆角,和鼠标放上去为红色。

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

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>

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

数据模板 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示例,如下所示:

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; }}
}

 

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; }}
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/583250.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言——数据类型

一、基本类型&#xff1a; 它们是构建其他数据类型的基础。 1、整型 用于表示整数。例如&#xff0c;int a 10; 整形中又有许多类型&#xff1a; 类型大小范围int2 或 4 字节-32,768 到 32,767 或 -2,147,483,648 到 2,147,483,647unsigned int2 或 4 字节0 到 65,535 或…

【zookeeper分布式锁】

文章目录 1.Zookeeper 分布式锁实战 1.Zookeeper 分布式锁实战 1.1 什么是分布式锁 在单体的应用开发场景中涉及并发同步的时候&#xff0c;大家往往采用Synchronized&#xff08;同步&#xff09;或者其他同一个 JVM内Lock机制来解决多线程间的同步问题。在分布式集群工作的开…

《MySQL系列-InnoDB引擎01》MySQL体系结构和存储引擎

文章目录 第一章 MySQL体系结构和存储引擎1 数据库和实例2 MySQL配置文件3 MySQL数据库路径4 MySQL体系结构5 MySQL存储引擎5.1 InnoDB存储引擎5.2 MyISAM存储引擎5.3 NDB存储引擎5.4 Memory存储引擎5.5 Archive存储引擎5.6 Federated存储引擎 6 连接MySQL6.1 TCP/IP6.2 命名管…

关于“Python”的核心知识点整理大全48

目录 world_population.py 16.2.5 制作世界地图 americas.py 16.2.6 在世界地图上呈现数字数据 na_populations.py 16.2.7 绘制完整的世界人口地图 world_population.py 16.2.8 根据人口数量将国家分组 world_population.py 16.2.9 使用 Pygal 设置世界地图的样式 w…

ubuntu快速搭建java开发环境/java1.8/idea2021.1.3/mysql/doceker

当设置Java开发环境时&#xff0c;确保先安装Java Development Kit (JDK) 8、IntelliJ IDEA 2021.1.3专业版、Maven、Git、MySQL和Docker。以下是Ubuntu上安装这些工具的基本步骤&#xff1a; 1. 安装Java Development Kit (JDK) 8&#xff1a; 首先&#xff0c;更新APT软件包…

Presentation Error:编程中的细节之战

Presentation Error&#xff1a;编程中的细节之战 大家好&#xff0c;我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天&#xff0c;让我们一起探讨在程序设计和编程中常见的问题之一…

PECL 到 LVPECL 的接口使用交流耦合或 3 电阻端接。采用交流耦合作热拔插时需注意防止因电容积累电荷放电导致器件损伤

交流耦合的必要性 PECL和LVPECL信号是差分信号,设计成具有一定的直流偏置电压。这种直流偏置电压在不同的设备或电路板之间可能会有所不同,直接连接可能导致直流偏置电平的冲突,从而损坏器件或影响信号完整性。交流耦合通过串联电容来隔离直流成分,只允许交流信号通过,从而…

web安全,常见的攻击以及如何防御

1、CSRF攻击 CSRF即Cross-site request forgery(跨站请求伪造) &#xff08;1&#xff09;为了防止这种攻击&#xff0c;表单一般都带有一个随机 token&#xff0c;告诉服务器这是真实请求。 <form action"your-bank.com/transfer" method"POST">&…

docker小白第九天

docker小白第九天 安装redis集群 cluster(集群)模式-docker版本&#xff0c;哈希槽分区进行亿级数据存储。如果1~2亿条数据需要缓存&#xff0c;请问如何设计这个存储案例。单机存储是不可能的&#xff0c;需要分布式存储&#xff0c;如果使用redis又该如何部署。 哈希取余分…

5-Docker实例-centos-nginx(3)

基于上次制作的centos-systemctl:1.0镜像,在其上安装nginx rpm,并构建nginx镜像。 1.制作nginx Dockerfile,并保存 命令: vim Dockerfile FROM centos-systemctl:1.0 MAINTAINER ztjCOPY nginx.repo /etc/yum.repos.d/ COPY epel.repo /etc/yum.repos.d/ COPY epel-tes…

数据结构——红黑树 and B-树

红黑树 根据平衡条件第4、5两点 最短路径&#xff0c;都是黑色 最长路径&#xff0c;红黑相间 最长是最短的两倍 B-树

Linux jed命令教程:如何有效地使用jed编辑器(附实例教程和注意事项)

Linux jed命令介绍 jed是一个可定制的文本编辑器&#xff0c;它在各种平台上都有应用&#xff0c;包括Linux、Windows、macOS等&#xff0c;但主要用于类Unix系统。jed特别适合用来编辑程序原始代码。 Linux jed命令适用的Linux版本 在Linux上&#xff0c;你的发行版的软件仓…

k8s-cni网络 10

Flannel vxlan模式跨主机通信原理 在同一个节点上的pod 流量通过cni网桥可以直接进行转发&#xff1b; 在需要跨主机访问时&#xff0c;数据包通过flannel(隧道) 知道另一边的mac地址&#xff0c;就可以拿到另一边的ip地址&#xff0c;然后构建常规的以太网数据包&#xff0c;…

QT+OSG/osgEarth编译之六十二:bsp+Qt编译(一套代码、一套框架,跨平台编译,版本:OSG-3.6.5插件库osgdb_ac)

目录 1、bsp介绍 2、文件分析 3、pro文件 4、编译实践 1、bsp介绍 BSP文件是使用Quake游戏引擎开发的游戏所使用的地图文件,它包含关卡地图的布局信息、对象和资源。许多著名的游戏都使用BSP地图文件,包括《雷神之锤》系列、《半条命》系列、《反恐精英》(CS)系列和《使…

HTML中img图片进行等比例缩放的实例代码

img图片等比例缩放的方法 HTML中&#xff0c;要修改img元素定义的图片的大小&#xff0c;且是等比例缩放&#xff0c;不改变宽和高的比值&#xff0c;那么可以采用只设置img元素属性中width和height中的任何一个&#xff0c;不要同时设置两个即可实现img图片的等比例缩放效果。…

泛目录是干什么用的蚂蚁seo泛程序

泛目录是干什么用的蚂蚁seo泛程序目录 泛目录是一种常见的网站优化方法&#xff0c;属于黑帽技术的一种。它的核心原理是利用高权重的网站继承目录&#xff0c;然后快速获得收录与排名。这种方法可以帮助网站在搜索引擎中获得更好的排名&#xff0c;从而吸引更多的流量。 泛目…

python字符串编码解码基础知识

python字符串编码解码基础知识 python通过ord©获取字符c的unicode的编码值&#xff0c;为整数。通过chr(i)获取i对应的unicode的字符。通过str.encode()将字符串编码为原始字节&#xff0c;b.decode()将原始字节解码为字符串。 1 字符串基础知识 python通过ord©获…

白话机器学习的数学-1-回归

1、设置问题 投入的广告费越多&#xff0c;广告的点击量就越高&#xff0c;进而带来访问数的增加。 2、定义模型 定义一个函数&#xff1a;一次函数 y ax b &#xff08;a 是斜率、b 是截距&#xff09; 定义函数&#xff1a; 3、最小二乘法 例子&#xff1a; 用随便确定的参…

flutter学习-day21-使用permission_handler进行系统权限的申请和操作

文章目录 1. 介绍2. 环境准备2-1. Android2-2. iOS 3. 使用 1. 介绍 在大多数操作系统上&#xff0c;权限不是在安装时才授予应用程序的。相反&#xff0c;开发人员必须在应用程序运行时请求用户的许可。在 flutter 开发中&#xff0c;则需要一个跨平台(iOS, Android)的 API 来…

计算机网络:知识回顾

0 本节主要内容 问题描述 解决思路 1 问题描述 通过一个应用场景来回顾计算机网络涉及到的协议&#xff08;所有层&#xff09;。如下图所示场景&#xff1a; 学生Bob将笔记本电脑用一根以太网电缆连接到学校的以太网交换机&#xff1b;交换机又与学校的路由器相连&#xf…