c# - 处理 Checked 的方式不同,具体取决于它是通过鼠标单击还是通过虚拟化调用

标签 c# wpf datagrid wpftoolkit

我有一个启用了虚拟化的 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/

相关文章:

c# - 如何在 .net 和 IIS 中启动具有受限权限的 native 进程

c# - 无法将 DateTime 从 EF "Code First"保存到 MySQL 远程数据库

c# - 当 ObservableCollection 值更新时,WPF Datagrid 绑定(bind)不更新

c# - 如何在关联的XAML中获取C#属性?

c# - Entity Framework 不插入记录

wpf - 每个单元格绑定(bind)一个数据网格一个对象

javascript - Akeneo:以编程方式选择网格过滤器

c# - 使用来自 .NET 应用程序的模板生成 HTML

c# - 在 Outlook 中捕获 BeforeItemCopy 事件

c# - Google.Apis.Admin.Email_Migration_v2 [HTTP状态码412 –已达到限制]