wpf模板之DataTemplate
前言
DataTemplate也称为数据模板, 是 WPF 中一个极其强大和核心的概念,它的主要作用是定义数据对象在 UI 上的可视化呈现方式,比如一个 Person 类的对象,如果将这个对象赋值给ContentControl 的Content属性,则默认只会显示其 调用ToString() 方法返回的结果,这通常不是我们想要的,我们想要将其转换为用户能看到和理解的视觉元素(如文本框、图片等),比如Person类有姓名属性、年龄属性、邮箱属性,我们想将这三个属性分为三行显示就需要借助DataTemplate。
1、应用于ContentControl
1.1代码
下面的代码中DataTemplate位于 Window.Resources中,并且它的的DataType属性指定了数据模板作用的类,也就是Person类,然后最外层是一个Border边框,里面是一个StackPanel容器,容器中放了TextBlock、StackPanel 、TextBlock ,其中第一个TextBlock绑定了Person类的Name属性;StackPanel里面有两个TextBlock,分别绑定了"Age:"字符串和Person类的Age属性;最后一个TextBlock绑定了Person类的Email属性。
1)xaml代码
<Window x:Class="DataTemplate之ContentControl.MainWindow"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:DataTemplate之ContentControl"mc:Ignorable="d"Title="MainWindow" Height="450" Width="800"><Window.Resources><DataTemplate DataType="{x:Type local:Person}"><Border Background="#FFE3F2FD" CornerRadius="10" Padding="15"BorderBrush="#FF90CAF9" BorderThickness="2"><StackPanel><TextBlock Text="{Binding Name}" FontSize="18" FontWeight="Bold"/><StackPanel Orientation="Horizontal" Margin="0,5,0,0"><TextBlock Text="Age: " FontWeight="SemiBold"/><TextBlock Text="{Binding Age}"/></StackPanel><TextBlock Text="{Binding Email}" TextDecorations="Underline" Foreground="Blue" Margin="0,5,0,0"/></StackPanel></Border></DataTemplate></Window.Resources><StackPanel Orientation="Vertical"><Button Content="{Binding person}" HorizontalAlignment="Center" VerticalAlignment="Center" /><Button Content="{Binding person}" HorizontalAlignment="Center" VerticalAlignment="Center" /><Button Content="{Binding person}" HorizontalAlignment="Center" VerticalAlignment="Center" /></StackPanel>
</Window>
2) ViewModelBase类
public class ViewModelBase{public event PropertyChangedEventHandler PropertyChanged;public void OnPropertyChanged(string propname){if (PropertyChanged != null){PropertyChanged(this, new PropertyChangedEventArgs(propname));}}}
3)ViewModel 类
public class ViewModel : INotifyPropertyChanged{public event PropertyChangedEventHandler PropertyChanged;Person _person;public Person person{get{return _person;}set{_person = value;PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("person"));}}public ViewModel(){person = new Person{Name = "张伟",Age = 28,Email = "zhangwei@example.com",};}}
4)MainWindow 类
public partial class MainWindow : Window{public MainWindow(){InitializeComponent();this.DataContext = new ViewModel();}}
window窗体放了1个StackPanel 并指定其中的子元素按照垂直方向排列,StackPanel 中添加了三个Button,并且每个Button的Content属性都绑定了ViewModel类中的person属性。
1. 2运行结果
可以看到Person类的对象的三个属性分别变成了Button控件中的三行。
2、应用于ItemsControl
2.1 代码
下面的代码中对于资源文件指定了key等于PersonDataTemplate,然后在Button中为ContentTemplate绑定资源文件PersonDataTemplate,在ListBox中为ItemTemplate绑定资源文件PersonDataTemplate。
1)xaml代码
<Window x:Class="DataTemplate之ContentControl.MainWindow"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:DataTemplate之ContentControl"mc:Ignorable="d"Title="MainWindow" Height="450" Width="800"><Window.Resources><DataTemplate x:Key="PersonDataTemplate" DataType="{x:Type local:Person}"><Border Background="#FFE3F2FD" CornerRadius="10" Padding="15"BorderBrush="#FF90CAF9" BorderThickness="2"><StackPanel><TextBlock Text="{Binding Name}" FontSize="18" FontWeight="Bold"/><StackPanel Orientation="Horizontal" Margin="0,5,0,0"><TextBlock Text="Age: " FontWeight="SemiBold"/><TextBlock Text="{Binding Age}"/></StackPanel><TextBlock Text="{Binding Email}" TextDecorations="Underline" Foreground="Blue" Margin="0,5,0,0"/></StackPanel></Border></DataTemplate></Window.Resources><StackPanel Orientation="Vertical"><Button ContentTemplate="{StaticResource PersonDataTemplate}" Content="{Binding person}" HorizontalAlignment="Center" VerticalAlignment="Center" /><ListBox ItemsSource="{Binding PersonList}" ItemTemplate="{StaticResource PersonDataTemplate}" HorizontalAlignment="Center"></ListBox></StackPanel>
</Window>
2) ViewModelBase类
public class ViewModelBase{public event PropertyChangedEventHandler PropertyChanged;public void OnPropertyChanged(string propname){if (PropertyChanged != null){PropertyChanged(this, new PropertyChangedEventArgs(propname));}}}
3)ViewModel 类
public class ViewModel : INotifyPropertyChanged{public event PropertyChangedEventHandler PropertyChanged;Person _person;public Person person{get{return _person;}set{_person = value;PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("person"));}}public ViewModel(){person = new Person{Name = "张伟",Age = 28,Email = "zhangwei@example.com",};PersonList = new ObservableCollection<Person>();PersonList.Add(new Person{Name = "小李",Age = 20,Email = "xiaoli@example.com",});PersonList.Add(new Person{Name = "小王",Age = 25,Email = "xiaowang@example.com",});}private ObservableCollection<Person> _personList;public ObservableCollection<Person> PersonList{get{return _personList;}set{_personList = value;PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("person"));}}}
4)MainWindow 类
public partial class MainWindow : Window{public MainWindow(){InitializeComponent();this.DataContext = new ViewModel();}}
window窗体放了1个StackPanel 并指定其中的子元素按照垂直方向排列,StackPanel 中添加了1个Button和1个ListBox,并且Button的Content属性绑定了ViewModel类中的person属性,ListBox的ItemsSource属性绑定了ViewModel类中的PersonList属性。
2.2 运行结果
可以看到Person类的对象的三个属性分别变成了Button控件中的3行,以及ListBox中的每一项的3行。
3、应用于DataGrid
3.1 代码
下面的代码中对于资源文件指定了key等于PersonDataTemplate,然后在DataGrid中为CellTemplate绑定资源文件PersonDataTemplate,这里需要注意的是DataGrid是为列绑定模板而不是为DataGrid绑定模板,所以不同列可以绑定不同模板,并且AutoGenerateColumns要设置为false,否则就会根据绑定的数据内容自动生成列;CanUserAddRows也要设置为false。
1)xaml代码
<Window x:Class="DataTemplate之ContentControl.MainWindow"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:DataTemplate之ContentControl"mc:Ignorable="d"Title="MainWindow" Height="450" Width="800"><Window.Resources><DataTemplate x:Key="PersonDataTemplate" DataType="{x:Type local:Person}"><Border Background="#FFE3F2FD" CornerRadius="10" Padding="15"BorderBrush="#FF90CAF9" BorderThickness="2"><StackPanel><TextBlock Text="{Binding Name}" FontSize="18" FontWeight="Bold"/><StackPanel Orientation="Horizontal" Margin="0,5,0,0"><TextBlock Text="Age: " FontWeight="SemiBold"/><TextBlock Text="{Binding Age}"/></StackPanel><TextBlock Text="{Binding Email}" TextDecorations="Underline" Foreground="Blue" Margin="0,5,0,0"/></StackPanel></Border></DataTemplate></Window.Resources><DataGrid ItemsSource="{Binding PersonList}" AutoGenerateColumns="False" CanUserAddRows="False" ><DataGrid.Columns><DataGridTemplateColumn Header="个人信息" CellTemplate="{StaticResource PersonDataTemplate}"/></DataGrid.Columns></DataGrid >
</Window>
32.2 运行结果
最终DataGrid会有一列,列名为“个人信息”。
马工撰写的年入30万+C#上位机项目实战必备教程(点击下方链接即可访问文章目录)
1、《C#串口通信从入门到精通》
2、《C#与PLC通信从入门到精通 》
3、《C# Modbus通信从入门到精通》
4、《C#Socket通信从入门到精通 》
5、《C# MES通信从入门到精通》
6、《winform控件从入门到精通》
7、《C#操作MySql数据库从入门到精通》