在上面的代码中,DataGrid中有一列DataGridTemplateColumn,其定义了数据模板。请问,如何查找到数据模板中的CheckBox?
<Window x:Class="WPF1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Grid HorizontalAlignment="Left" Width="596"> <DataGrid Name="datagrid1" Margin="123,78,81,158" AutoGenerateColumns="False" Height="131"> <DataGrid.Columns> <DataGridTemplateColumn Width="80" Header="序号"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <Grid Width="50" Margin="0 0 25 0"> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition Width="auto"/> </Grid.ColumnDefinitions> <TextBlock HorizontalAlignment="Right" Text="张三"/> <CheckBox Name="PART_XhCheckBox" Grid.Column="1" Margin="5 1.5 0 0" /> </Grid> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid> </Grid> </Window> /pre> |
|
5分 |
|
你说的这些方法我是掌握了的。不过,不能解决此问题呢 |
|
30分 |
要找到数据模板中的CheckBox元素,可以用DataTemplate.FindName(string name, FrameworkElement parent)方法。
strong>但是,不建议直接操作CheckBox元素,因为DataGrid一般会启用虚拟模式。而在虚拟模式下,当前没有显示的单元格,可以不用实例化模板(节省内存)。如果具体某个单元格的模板不实例化,你就没有办法操纵该单元格的CheckBox元素。 strong>正确的办法是操纵数据,而不是去操纵模板元素。 比如下面的例子: 在窗口空白部分单击左键,会用DataTemplate.FindName来反选Checkbox,当数据比较多的时候,你会发现它只改变一部分。 在窗口空白部分单击右键,会对绑定数据进行反选,你会发现它代码简单,却可以正确地更新所有数据和UI。 pre class=”brush: html”><Window x:Class=”WPF1.MainWindow” xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation” xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml” MouseLeftButtonDown=”Window_MouseLeftButtonDown” MouseRightButtonDown=”Window_MouseRightButtonDown” Title=”MainWindow” Height=”350″ Width=”525″> <Grid HorizontalAlignment=”Left” Width=”596″> <DataGrid Name=”datagrid1″ Margin=”123,78,81,158″ AutoGenerateColumns=”False” Height=”131″> <DataGrid.Columns> <DataGridTemplateColumn Width=”80″ Header=”序号”> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <Grid Width=”50″ Margin=”0 0 25 0″> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition Width=”auto”/> </Grid.ColumnDefinitions> <TextBlock HorizontalAlignment=”Right” Text=”{Binding Name}”/> <CheckBox Name=”PART_XhCheckBox” Grid.Column=”1″ Margin=”5 1.5 0 0″ IsChecked=”{Binding Valid}” /> </Grid> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid> </Grid> </Window> pre class=”brush: csharp”> namespace WPF1 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); for (int i = 0; i < 40; i++) { list.Add(new My() { Name = “张三” + i }); } this.datagrid1.ItemsSource = list; } ObservableCollection<My> list = new ObservableCollection<My>(); private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { // 寻找PART_XhCheckBox,并进行反选。对某些不可见单元格可能无效 DataGridTemplateColumn column = this.datagrid1.Columns[0] as DataGridTemplateColumn; foreach (var item in this.datagrid1.Items) { var element = column.GetCellContent(item); if (element != null) { CheckBox cb = column.CellTemplate.FindName(“PART_XhCheckBox”, element) as CheckBox; cb.IsChecked = !cb.IsChecked; } } } private void Window_MouseRightButtonDown(object sender, MouseButtonEventArgs e) { // 操纵数据,直接进行反选 foreach (My my in list) { my.Valid = !my.Valid; } } } class My : INotifyPropertyChanged { string name; public string Name { get { return name; } set { name = value; FirePropertyChanged(“Name”); } } bool valid; public bool Valid { get { return valid; } set { valid = value; FirePropertyChanged(“Valid”); } } public event PropertyChangedEventHandler PropertyChanged; void FirePropertyChanged(string propertyName) { var propertyChanged = this.PropertyChanged; if (propertyChanged != null) propertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } } /div> |
5分 |
9楼例子请加上如下改变,手动选择才更新到绑定数据。
<CheckBox Name=”PART_XhCheckBox” Grid.Column=”1″ Margin=”5 1.5 0 0″ IsChecked=”{Binding Valid, UpdateSourceTrigger=PropertyChanged}” /> |