DataTemplate可以说是WPF的灵魂之一。可以灵活的定制样式和动态添加控件。
今天先来了解DataTemplate通常使用(DataGrid的DataTemplate)
(代码中有些方法,你可以参考之前的blog)
XAML的代码:
<Window x:Class="WpfApplication4.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:local="clr-namespace:WpfApplication4" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Grid> <DataGrid ItemsSource="{Binding ItemList}" AutoGenerateColumns="False" SelectedItem="{Binding SelectedItems}"> <DataGrid.Columns> <DataGridTemplateColumn> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <CheckBox IsChecked="{Binding IsChecked,Mode=TwoWay}" local:CheckBoxBehavior.Click="{Binding DataContext.ClickCommand, RelativeSource={RelativeSource AncestorType={x:Type Window},Mode=FindAncestor}}"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <DataGridTextColumn Header="名字" Width="500" Binding="{Binding Name,Mode=TwoWay}"/> </DataGrid.Columns> </DataGrid> </Grid> </Window>
DataTemplate下的Click绑定可以参考系列2。使用RelativeSource(相对资源)来绑定的原因是:DataTemplate当前的DataCotext是DataGrid 单个Item的DataContext.
不用相对资源,无法绑定到ViewModel ClickCommand. 之于什么是相对资源可以查google;
下面是ViewModel代码:
using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; namespace WpfApplication4 { public class MainWindowsViewModel:NotifyObject { #region << Property >> public ObservableCollection<DataGridItem> ItemList { get; set; } public ICommand ClickCommand { get; set; } public DataGridItem SelectedItems { get; set; } #endregion #region << Constructor >> public MainWindowsViewModel() { ItemList = new ObservableCollection<DataGridItem>(); InitItemList(); ClickCommand = new DeletegateCommand(Click); } #endregion #region << Method >> private void InitItemList() { ///打桩数据 ItemList.Add(new DataGridItem("Demo1")); ItemList.Add(new DataGridItem("Demo2")); ItemList.Add(new DataGridItem("Demo3")); ItemList.Add(new DataGridItem("Demo4")); ItemList.Add(new DataGridItem("Demo5")); } public void Click() { if (SelectedItems != null) { SelectedItems.Name = "Selected"; } } #endregion } public class DataGridItem:NotifyObject { #region << Property >> public bool IsChecked { get { return GET(() => IsChecked); } set { SET(() => IsChecked, value); } } public string Name { get { return GET(() => Name); } set { SET(() => Name, value); } } #endregion #region << Constructor >> public DataGridItem(string name):this(false,name) { } public DataGridItem(bool isChecked, string name) { IsChecked = true ; Name = name; } #endregion } }
这个ViewModel中关于ObservableCollection这个类的使用有以下的注意点:
1.ObservableCollection自身提供了通知功能。但要注意的是他的通用功能,只针对添加子元素和删除子元素。当子元素自身属性(子元素自身变化不通知)发生变化的时候,他是不会通知的。
2:List ObservableCollection之间的转换;
List demo = new List(ObservableCollection);