首页 > 解决方案 > WPF DataGrid设置EnableRowVirtualization为true,无法获取复选框

问题描述

我有超过 1000 条数据要显示在 WPF 的 DataGrid 中,并且我在 DataGrid 中添加了一个复选框。选择多个复选框时,可以将所选索引添加到指定的集合中。代码如下:

XAML:</p>

<DataGrid x:Name="textWmdg" AutoGenerateColumns="False" Grid.Row="0"  VerticalAlignment="Top" ItemsSource="{Binding waterTexts}" Height="252" **EnableRowVirtualization="True"**
CanUserSortColumns="False"  Margin="2,2,2,2"  
VirtualizingPanel.VirtualizationMode="Standard"
CanUserResizeColumns="False" CanUserResizeRows="False" RowHeaderWidth="0"
CanUserReorderColumns="False" CanUserAddRows="False" Style="{StaticResource DataGridStyle}"VirtualizingPanel.IsVirtualizing="True" DataGrid.RowHeight="22" RowDetailsVisibilityMode="Visible" LoadingRow="TextWmdg_LoadingRow">
   <DataGrid.Columns>
       <DataGridTemplateColumn Header="Select" Width="*" IsReadOnly="False">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                     <StackPanel Orientation="Horizontal" >
                          <CheckBox x:Name="textSelect" Click="TextSelected_Click"/>
                     </StackPanel>
                 </DataTemplate>
             </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <DataGridTextColumn Header="NO." Width="*" Binding="{Binding Header, RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}, Mode=FindAncestor}}" IsReadOnly="True"/>
              <DataGridTemplateColumn Header="Color" Width="3*" IsReadOnly="True">
                  <DataGridTemplateColumn.CellTemplate>
                      <DataTemplate>
                          <StackPanel Orientation="Horizontal" >
                               <Label Width="15" BorderThickness="0.5" BorderBrush="Black" Background="{Binding TextColor}"/>
                           </StackPanel>
                       </DataTemplate>
                   </DataGridTemplateColumn.CellTemplate>
                 </DataGridTemplateColumn>
               <DataGridTextColumn Header="Sign" Width="3*" Binding="{Binding Sign}" IsReadOnly="True"/>
               <DataGridTemplateColumn Header="KeyWord" Width="12*" IsReadOnly="True">
                   <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding ShowText}" TextAlignment="Left" HorizontalAlignment="Left">
                                <TextBlock.ToolTip>
                             <TextBlock Text="{Binding ShowText}" TextWrapping="Wrap"/>
                             </TextBlock.ToolTip>
                             </TextBlock>
                        </DataTemplate>
                     </DataGridTemplateColumn.CellTemplate>
                   </DataGridTemplateColumn>
                </DataGrid.Columns>
             </DataGrid>

CS:

private void TextSelected_Click(object sender, RoutedEventArgs e)
{

    deltextindex.Clear();

    for (int i = 0; i < textWmdg.Items.Count; i++)
    {

        DataGridTemplateColumn selectcolumn = textWmdg.Columns[0] as DataGridTemplateColumn;

        FrameworkElement selectment = selectcolumn.GetCellContent(textWmdg.Items[i]);

        CheckBox textcheckbox = selectcolumn.CellTemplate.FindName("textSelect", selectment) as CheckBox;

        if (textcheckbox.IsChecked == true)
        {
            deltextindex.Add(i);
        }
    }

}

之前一直没有问题,但是显示速度很慢。今天为了追求更快的速度,将DataGrid的EnableRowVirtualization设置为true,结果无法正常获取复选框。提示System.ArgumentNullException。如果我可以提高显示速度并正确获取复选框的索引怎么办?谢谢你!

标签: c#wpf

解决方案


如果您IsTextSelected在视图模型上创建一个属性并将其绑定到CheckBox.IsChecked属性怎么办?

<DataGridTemplateColumn Header="Select" Width="*" IsReadOnly="False">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal" >
                <CheckBox IsChecked="{Binding IsTextSelected"} Click="TextSelected_Click"/>
            </StackPanel>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

然后您可以检查哪些项目已IsTextSelected设置为 true。

private void TextSelected_Click(object sender, RoutedEventArgs e)
{
    deltextindex.Clear();
    for (int i = 0; i < textWmdg.Items.Count; i++)
    {
        var viewModel = textWmdg.Items[i] as YourViewModelType;
        if (viewModel.IsTextSelected)
        {
            deltextindex.Add(i);
        }
    }
}

推荐阅读