模板描述了控件的整体外观和视觉外观.对于每个控件,都有一个与之关联的默认模板,它为该控件提供外观.在WPF应用程序中,当您想要自定义控件的可视行为和可视外观时,可以轻松创建自己的模板.逻辑和模板之间的连接可以通过数据绑定来实现.
在MVVM中,还有另一种主要形式,称为ViewModel的第一个构造.
ViewModel第一种构造方法利用WPF中隐式数据模板的功能.
隐式数据模板可以自动从当前资源字典中为使用数据绑定的元素选择适当的模板.它们基于数据绑定呈现的数据对象的类型来执行此操作.首先,你需要有一些绑定到数据对象的元素.
让我们再来看看我们的简单例子您将了解如何首先利用数据模板,特别是隐式数据模板来查看模型.这是我们的StudentViewModel类的实现.
using MVVMDemo.Model; using System.Collections.ObjectModel; namespace MVVMDemo.ViewModel { public class StudentViewModel { public StudentViewModel() { LoadStudents(); } public ObservableCollection<Student> Students { get; set; } public void LoadStudents() { ObservableCollection<Student> students = new ObservableCollection<Student>(); students.Add(new Student { FirstName = "Mark", LastName = "Allain" }); students.Add(new Student { FirstName = "Allen", LastName = "Brown" }); students.Add(new Student { FirstName = "Linda", LastName = "Hamerski" }); Students = students; } } }
您可以看到上面的ViewModel未更改.我们将继续前一章中的相同示例.此ViewModel类只公开Students集合属性并在构造时填充它.让我们转到StudentView.xaml文件,删除现有的实现并在参考资料部分定义一个数据模板.
<UserControl.Resources> <DataTemplate x:Key = "studentsTemplate"> <StackPanel Orientation = "Horizontal"> <TextBox Text = "{Binding Path = FirstName, Mode = TwoWay}" Width = "100" Margin = "3 5 3 5"/> <TextBox Text = "{Binding Path = LastName, Mode = TwoWay}" Width = "100" Margin = "0 5 3 5"/> <TextBlock Text = "{Binding Path = FullName, Mode = OneWay}" Margin = "0 5 3 5"/> </StackPanel> </DataTemplate> </UserControl.Resources>
现在添加一个列表框,数据将该列表框绑定到Students属性,如下面的代码所示.
<ListBox ItemsSource = "{Binding Students}" ItemTemplate = "{StaticResource studentsTemplate}"/>
在Resource部分中,DataTemplate有一个studentTemplate键,然后实际使用该模板,我们需要使用ListBox的ItemTemplate属性.所以现在您可以看到我们指示列表框使用该特定模板来呈现这些学生.以下是StudentView.xaml文件的完整实现.
<UserControl x:Class = "MVVMDemo.Views.StudentView" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:local = "clr-namespace:MVVMDemo.Views" xmlns:viewModel = "clr-namespace:MVVMDemo.ViewModel" xmlns:vml = "clr-namespace:MVVMDemo.VML" vml:ViewModelLocator.AutoHookedUpViewModel = "True" mc:Ignorable = "d" d:DesignHeight = "300" d:DesignWidth = "300"> <UserControl.Resources> <DataTemplate x:Key = "studentsTemplate"> <StackPanel Orientation = "Horizontal"> <TextBox Text = "{Binding Path = FirstName, Mode = TwoWay}" Width = "100" Margin = "3 5 3 5"/> <TextBox Text = "{Binding Path = LastName, Mode = TwoWay}" Width = "100" Margin = "0 5 3 5"/> <TextBlock Text = "{Binding Path = FullName, Mode = OneWay}" Margin = "0 5 3 5"/> </StackPanel> </DataTemplate> </UserControl.Resources> <Grid> <ListBox ItemsSource = "{Binding Students}" ItemTemplate = "{StaticResource studentsTemplate}"/> </Grid> </UserControl>
编译并执行上述代码时,您将看到以下窗口,其中包含一个ListBox.每个ListBoxItem包含显示在TextBlock和Text框中的Student类对象数据.
要使其成为隐式模板,我们需要从列表框中删除ItemTemplate属性,并在模板定义中添加DataType属性,如下面的代码所示.
<UserControl.Resources> <DataTemplate DataType = "{x:Type data:Student}"> <StackPanel Orientation = "Horizontal"> <TextBox Text = "{Binding Path = FirstName, Mode = TwoWay}" Width = "100" Margin = "3 5 3 5"/> <TextBox Text = "{Binding Path = LastName, Mode = TwoWay}" Width = "100" Margin = "0 5 3 5"/> <TextBlock Text = "{Binding Path = FullName, Mode = OneWay}" Margin = "0 5 3 5"/> </StackPanel> </DataTemplate> </UserControl.Resources> <Grid> <ListBox ItemsSource = "{Binding Students}"/> </Grid>
在DataTemplate中,x:Type标记扩展非常重要,就像XAML中的一种运算符一样.所以,基本上我们需要指向MVVMDemo.Model命名空间中的Student数据类型.以下是更新的完整XAML文件.
<UserControl x:Class="MVVMDemo.Views.StudentView" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:local = "clr-namespace:MVVMDemo.Views" xmlns:viewModel = "clr-namespace:MVVMDemo.ViewModel" xmlns:data = "clr-namespace:MVVMDemo.Model" xmlns:vml = "clr-namespace:MVVMDemo.VML" vml:ViewModelLocator.AutoHookedUpViewModel = "True" mc:Ignorable = "d" d:DesignHeight = "300" d:DesignWidth = "300"> <UserControl.Resources> <DataTemplate DataType = "{x:Type data:Student}"> <StackPanel Orientation = "Horizontal"> <TextBox Text = "{Binding Path = FirstName, Mode = TwoWay}" Width = "100" Margin = "3 5 3 5"/> <TextBox Text = "{Binding Path = LastName, Mode = TwoWay}" Width = "100" Margin = "0 5 3 5"/> <TextBlock Text = "{Binding Path = FullName, Mode = OneWay}" Margin = "0 5 3 5"/> </StackPanel> </DataTemplate> </UserControl.Resources> <Grid> <ListBox ItemsSource = "{Binding Students}"/> </Grid> </UserControl>
当你再次运行这个应用程序时,你仍然可以获得带有数据模板的Students的相同渲染,因为它会自动映射正在渲染的对象的类型找到合适的DataTemplate.
我们建议您执行上面的例子是一步一步的方法,以便更好地理解.