<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>
在上面的代码中,DataGrid中有一列DataGridTemplateColumn,其定义了数据模板。
请问,如何查找到数据模板中的CheckBox?
------解决思路----------------------
http://blog.csdn.net/duanzi_peng/article/details/17094639
获取子元素方法。
------解决思路----------------------
要找到数据模板中的CheckBox元素,可以用DataTemplate.FindName(string name, FrameworkElement parent)方法。
但是,不建议直接操作CheckBox元素,因为DataGrid一般会启用虚拟模式。而在虚拟模式下,当前没有显示的单元格,可以不用实例化模板(节省内存)。如果具体某个单元格的模板不实例化,你就没有办法操纵该单元格的CheckBox元素。
正确的办法是操纵数据,而不是去操纵模板元素。
比如下面的例子:
在窗口空白部分单击左键,会用DataTemplate.FindName来反选Checkbox,当数据比较多的时候,你会发现它只改变一部分。
在窗口空白部分单击右键,会对绑定数据进行反选,你会发现它代码简单,却可以正确地更新所有数据和UI。
<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>
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));
}
}
}
------解决思路----------------------
9楼例子请加上如下改变,手动选择才更新到绑定数据。
<CheckBox Name="PART_XhCheckBox" Grid.Column="1" Margin="5 1.5 0 0" IsChecked="{Binding Valid, UpdateSourceTrigger=PropertyChanged}" />