我有一个打开虚拟化的WPF工具包数据网格。每行都有一个复选框绑定到底层模型中的bool。
复选框(除数据绑定外)还有Checked和Unchecked处理程序(!),如果您单击选中多行,则允许一次检查多个项目。
这是xaml:
<Controls:DataGrid ItemsSource="{Binding UnderlyingData}"
AutoGenerateColumns="False"
HeadersVisibility="Column">
<Controls:DataGrid.Columns>
<Controls:DataGridTemplateColumn Header="Use?" SortMemberPath="Use">
<Controls:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox Style="{StaticResource DataGridCheckBoxStyle}" IsChecked="{Binding Spike}"
Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked" />
</DataTemplate>
</Controls:DataGridTemplateColumn.CellTemplate>
</Controls:DataGridTemplateColumn>
</Controls:DataGrid.Columns>
</Controls:DataGrid>
Checked / Unchecked处理程序:
private void CheckBox_Checked(object sender, RoutedEventArgs e)
{
if (!processingMultipleRows)
{
UpdateAllSelected(e.OriginalSource as ToggleButton);
e.Handled = true;
}
}
private void CheckBox_Unchecked(object sender, RoutedEventArgs e)
{
if (!processingMultipleRows)
{
UpdateAllSelected(e.OriginalSource as ToggleButton);
e.Handled = true;
}
}
private void UpdateAllSelected(ToggleButton checkBox)
{
processingMultipleRows= true;
var include = checkBox.IsChecked ?? false;
tickBoxSelector.ApplyToAllSelected<RowViewModel>(checkBox, p => p.Use = include);
ViewModel.ProcessUseStateChange();
processingMultipleRows= false;
}
此代码除了一个以外的所有方式都有效。 ViewModel.ProcessUseStateChange()相当慢,每当您切换一个或多个CheckBox时,它都会被调用一次。这很好,但是当您滚动数据网格时,它也会在视图中出现的每个新行调用一次,因为虚拟化意味着必须创建新行并且必须设置它们的检查状态。
是否有一种狡猾的方法来确定是否响应鼠标单击或因虚拟化而导致新行的实例化而调用Checked?
答案 0 :(得分:2)
我最终找到的解决方案是处理Click事件,而不是Checked / Unchecked,这个简化的事情非常简单:
<Controls:DataGrid ItemsSource="{Binding UnderlyingData}"
AutoGenerateColumns="False"
HeadersVisibility="Column">
<Controls:DataGrid.Columns>
<Controls:DataGridTemplateColumn Header="Use?" SortMemberPath="Use">
<Controls:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox Style="{StaticResource DataGridCheckBoxStyle}" IsChecked="{Binding Spike}"
Click="CheckBox_Clicked"/>
</DataTemplate>
</Controls:DataGridTemplateColumn.CellTemplate>
</Controls:DataGridTemplateColumn>
</Controls:DataGrid.Columns>
</Controls:DataGrid>
和
private void CheckBox_Clicked(object sender, RoutedEventArgs e)
{
UpdateAllSelected(e.OriginalSource as ToggleButton);
e.Handled = true;
}
private void UpdateAllSelected(ToggleButton checkBox)
{
var include = checkBox.IsChecked ?? false;
tickBoxSelector.ApplyToAllSelected<RowViewModel>(checkBox, p => p.Use = include);
ViewModel.ProcessUseStateChange();
}