我有一个启用了虚拟化的 WPF 工具包数据网格。每行都有一个复选框绑定(bind)到基础模型中的 bool 值。
复选框(除了数据绑定(bind)之外)还有已选中和未选中处理程序 (!),如果您在选中多行的情况下单击一个项目,则允许一次选中多个项目。
这是 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>
以及选中/未选中处理程序:
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 就会调用一次。这很好,但是当您滚动数据网格时,它也会针对出现在 View 中的每一行调用一次,因为虚拟化意味着必须创建新行并且必须设置它们的检查状态。
是否有一种巧妙的方法来确定是否调用 Checked 以响应鼠标单击或由于虚拟化而实例化新行?
最佳答案
我最后找到的解决方案是处理 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();
}
关于c# - 处理 Checked 的方式不同,具体取决于它是通过鼠标单击还是通过虚拟化调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3785432/