如何在datagrid中点击复选框列标题显示弹出菜单?

时间:2022-02-27 19:39:33

I am using the datagrid from WPF toolkit in a WPF windows application. It has a datatemplate in the rowheader which creates a checkbox column used for selecting the rows.

我在WPF Windows应用程序中使用WPF工具包中的datagrid。它在rowheader中有一个datatemplate,它创建一个用于选择行的复选框列。

If you click on the header row of the checkbox column (the top leftmost cell in the grid), it will check all the checkboxes in the grid thereby selecting all the rows.

如果单击复选框列的标题行(网格中最左上角的单元格),它将检查网格中的所有复选框,从而选择所有行。

Relevant portions from the xaml

来自xaml的相关部分

<Window x:Class="Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:toolkit="http://schemas.microsoft.com/wpf/2008/toolkit" >

<toolkit:DataGrid Name="dataGrid" ItemsSource="{Binding}" 
AutoGenerateColumns="True" SelectionMode="Extended" CanResizeRows="False">
    <toolkit:DataGrid.RowHeaderTemplate>
        <DataTemplate>
            <Grid>
                <CheckBox IsChecked="{
                Binding Path=IsSelected, 
                Mode=TwoWay, 
                RelativeSource={RelativeSource FindAncestor, 
                AncestorType={x:Type toolkit:DataGridRow}}}"
                />
            </Grid>
        </DataTemplate>
    </toolkit:DataGrid.RowHeaderTemplate>
</toolkit:DataGrid>
</Window>

Now I want to know how to handle this click. I plan to handle that and show a popup menu instead.

现在我想知道如何处理这个点击。我计划处理它并显示一个弹出菜单。

Which control's click event should I wire for this?

我应该为哪个控件的点击事件接线?

Answer: using SelectAllCommand to handle the events like so (example)

答:使用SelectAllCommand来处理这样的事件(例子)

datagrid.CommandBindings.Add(new CommandBinding(
Microsoft.Windows.Controls.DataGrid.SelectAllCommand, 
OnSelectAll, CanExecuteSelectAll));
public void OnSelectAll(object sender, ExecutedRoutedEventArgs e)
    {
        MessageBox.Show("All Selected");
    }
public void CanExecuteSelectAll(object sender, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = true;
        Console.WriteLine("Can I execute?");
    }

1 个解决方案

#1


If you expand the DataGrid ControlTemplate you can see that there is a Button which is bound to the SelectAllCommand.

如果展开DataGrid ControlTemplate,您可以看到有一个绑定到SelectAllCommand的Button。

<Window x:Class="WpfApplication1.Window3"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:toolkit="http://schemas.microsoft.com/wpf/2008/toolkit"
Title="Window3" Height="500" Width="500"
Loaded="Window_Loaded">
<Window.Resources>
    <Style x:Key="DataGridStyle1" TargetType="{x:Type toolkit:DataGrid}">
        <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
        <Setter Property="BorderBrush" Value="#FF688CAF"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="RowDetailsVisibilityMode" Value="VisibleWhenSelected"/>
        <Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type toolkit:DataGrid}">
                    <Border SnapsToDevicePixels="True" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}">
                        <ScrollViewer x:Name="DG_ScrollViewer" Focusable="False">
                            <ScrollViewer.Template>
                                <ControlTemplate TargetType="{x:Type ScrollViewer}">
                                    <Grid>
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="Auto"/>
                                            <ColumnDefinition Width="*"/>
                                            <ColumnDefinition Width="Auto"/>
                                        </Grid.ColumnDefinitions>
                                        <Grid.RowDefinitions>
                                            <RowDefinition Height="Auto"/>
                                            <RowDefinition Height="*"/>
                                            <RowDefinition Height="Auto"/>
                                        </Grid.RowDefinitions>
                                        <Button Command="{x:Static toolkit:DataGrid.SelectAllCommand}"
                                         Width="{Binding CellsPanelHorizontalOffset, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type toolkit:DataGrid}}}" Focusable="False">
                                            <Button.Template>
                                                <ControlTemplate TargetType="{x:Type Button}">
                                                    <Grid>
                                                        <Rectangle x:Name="Border" Fill="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" SnapsToDevicePixels="True"/>
                                                        <Polygon x:Name="Arrow" Fill="Black" Stretch="Uniform" HorizontalAlignment="Right" Margin="8,8,3,3" VerticalAlignment="Bottom" Opacity="0.15" Points="0,10 10,10 10,0"/>
                                                    </Grid>
                                                    <ControlTemplate.Triggers>
                                                        <Trigger Property="IsMouseOver" Value="True">
                                                            <Setter Property="Stroke" TargetName="Border" Value="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}"/>
                                                        </Trigger>
                                                        <Trigger Property="IsPressed" Value="True">
                                                            <Setter Property="Fill" TargetName="Border" Value="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}"/>
                                                        </Trigger>
                                                        <Trigger Property="IsEnabled" Value="False">
                                                            <Setter Property="Visibility" TargetName="Arrow" Value="Collapsed"/>
                                                        </Trigger>
                                                    </ControlTemplate.Triggers>
                                                </ControlTemplate>
                                            </Button.Template>
                                            <Button.Visibility>
                                                <Binding Path="HeadersVisibility" RelativeSource="{RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type toolkit:DataGrid}}">
                                                    <Binding.ConverterParameter>
                                                        <toolkit:DataGridHeadersVisibility>All</toolkit:DataGridHeadersVisibility>
                                                    </Binding.ConverterParameter>
                                                </Binding>
                                            </Button.Visibility>
                                        </Button>
                                        <toolkit:DataGridColumnHeadersPresenter x:Name="PART_ColumnHeadersPresenter" Grid.Column="1">
                                            <toolkit:DataGridColumnHeadersPresenter.Visibility>
                                                <Binding Path="HeadersVisibility" RelativeSource="{RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type toolkit:DataGrid}}">
                                                    <Binding.ConverterParameter>
                                                        <toolkit:DataGridHeadersVisibility>Column</toolkit:DataGridHeadersVisibility>
                                                    </Binding.ConverterParameter>
                                                </Binding>
                                            </toolkit:DataGridColumnHeadersPresenter.Visibility>
                                        </toolkit:DataGridColumnHeadersPresenter>
                                        <ScrollContentPresenter x:Name="PART_ScrollContentPresenter" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" ContentTemplate="{TemplateBinding ContentTemplate}" Grid.ColumnSpan="2" Grid.Row="1" CanContentScroll="{TemplateBinding CanContentScroll}" CanHorizontallyScroll="False" CanVerticallyScroll="False"/>
                                        <ScrollBar x:Name="PART_VerticalScrollBar" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Grid.Column="2" Grid.Row="1" Maximum="{TemplateBinding ScrollableHeight}" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" Orientation="Vertical" ViewportSize="{TemplateBinding ViewportHeight}"/>
                                        <Grid Grid.Column="1" Grid.Row="2">
                                            <Grid.ColumnDefinitions>
                                                <ColumnDefinition Width="{Binding NonFrozenColumnsViewportHorizontalOffset, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type toolkit:DataGrid}}}"/>
                                                <ColumnDefinition Width="*"/>
                                            </Grid.ColumnDefinitions>
                                            <ScrollBar x:Name="PART_HorizontalScrollBar" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Grid.Column="1" Maximum="{TemplateBinding ScrollableWidth}" Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" Orientation="Horizontal" ViewportSize="{TemplateBinding ViewportWidth}"/>
                                        </Grid>
                                    </Grid>
                                </ControlTemplate>
                            </ScrollViewer.Template>
                            <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                        </ScrollViewer>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <Trigger Property="IsGrouping" Value="True">
                <Setter Property="ScrollViewer.CanContentScroll" Value="False"/>
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>
<Grid>
    <toolkit:DataGrid Name="dataGrid" 
                      ItemsSource="{Binding}"
                      CanUserResizeRows="False" 
                      SelectionMode="Extended" 
                      AutoGenerateColumns="True" Style="{DynamicResource DataGridStyle1}">
        <toolkit:DataGrid.RowHeaderTemplate>
            <DataTemplate>
                <Grid>
                    <CheckBox IsChecked="{
                        Binding Path=IsSelected, 
                        Mode=TwoWay, 
                        RelativeSource={RelativeSource FindAncestor, 
                        AncestorType={x:Type toolkit:DataGridRow}}}"
                        />
                </Grid>
            </DataTemplate>
        </toolkit:DataGrid.RowHeaderTemplate>
    </toolkit:DataGrid>
</Grid>

You can override that Button's Command to perform your own logic or even replace the button with a different control.

您可以覆盖该Button的Command来执行您自己的逻辑,甚至可以用不同的控件替换该按钮。

#1


If you expand the DataGrid ControlTemplate you can see that there is a Button which is bound to the SelectAllCommand.

如果展开DataGrid ControlTemplate,您可以看到有一个绑定到SelectAllCommand的Button。

<Window x:Class="WpfApplication1.Window3"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:toolkit="http://schemas.microsoft.com/wpf/2008/toolkit"
Title="Window3" Height="500" Width="500"
Loaded="Window_Loaded">
<Window.Resources>
    <Style x:Key="DataGridStyle1" TargetType="{x:Type toolkit:DataGrid}">
        <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
        <Setter Property="BorderBrush" Value="#FF688CAF"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="RowDetailsVisibilityMode" Value="VisibleWhenSelected"/>
        <Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type toolkit:DataGrid}">
                    <Border SnapsToDevicePixels="True" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}">
                        <ScrollViewer x:Name="DG_ScrollViewer" Focusable="False">
                            <ScrollViewer.Template>
                                <ControlTemplate TargetType="{x:Type ScrollViewer}">
                                    <Grid>
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="Auto"/>
                                            <ColumnDefinition Width="*"/>
                                            <ColumnDefinition Width="Auto"/>
                                        </Grid.ColumnDefinitions>
                                        <Grid.RowDefinitions>
                                            <RowDefinition Height="Auto"/>
                                            <RowDefinition Height="*"/>
                                            <RowDefinition Height="Auto"/>
                                        </Grid.RowDefinitions>
                                        <Button Command="{x:Static toolkit:DataGrid.SelectAllCommand}"
                                         Width="{Binding CellsPanelHorizontalOffset, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type toolkit:DataGrid}}}" Focusable="False">
                                            <Button.Template>
                                                <ControlTemplate TargetType="{x:Type Button}">
                                                    <Grid>
                                                        <Rectangle x:Name="Border" Fill="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" SnapsToDevicePixels="True"/>
                                                        <Polygon x:Name="Arrow" Fill="Black" Stretch="Uniform" HorizontalAlignment="Right" Margin="8,8,3,3" VerticalAlignment="Bottom" Opacity="0.15" Points="0,10 10,10 10,0"/>
                                                    </Grid>
                                                    <ControlTemplate.Triggers>
                                                        <Trigger Property="IsMouseOver" Value="True">
                                                            <Setter Property="Stroke" TargetName="Border" Value="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}"/>
                                                        </Trigger>
                                                        <Trigger Property="IsPressed" Value="True">
                                                            <Setter Property="Fill" TargetName="Border" Value="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}"/>
                                                        </Trigger>
                                                        <Trigger Property="IsEnabled" Value="False">
                                                            <Setter Property="Visibility" TargetName="Arrow" Value="Collapsed"/>
                                                        </Trigger>
                                                    </ControlTemplate.Triggers>
                                                </ControlTemplate>
                                            </Button.Template>
                                            <Button.Visibility>
                                                <Binding Path="HeadersVisibility" RelativeSource="{RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type toolkit:DataGrid}}">
                                                    <Binding.ConverterParameter>
                                                        <toolkit:DataGridHeadersVisibility>All</toolkit:DataGridHeadersVisibility>
                                                    </Binding.ConverterParameter>
                                                </Binding>
                                            </Button.Visibility>
                                        </Button>
                                        <toolkit:DataGridColumnHeadersPresenter x:Name="PART_ColumnHeadersPresenter" Grid.Column="1">
                                            <toolkit:DataGridColumnHeadersPresenter.Visibility>
                                                <Binding Path="HeadersVisibility" RelativeSource="{RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type toolkit:DataGrid}}">
                                                    <Binding.ConverterParameter>
                                                        <toolkit:DataGridHeadersVisibility>Column</toolkit:DataGridHeadersVisibility>
                                                    </Binding.ConverterParameter>
                                                </Binding>
                                            </toolkit:DataGridColumnHeadersPresenter.Visibility>
                                        </toolkit:DataGridColumnHeadersPresenter>
                                        <ScrollContentPresenter x:Name="PART_ScrollContentPresenter" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" ContentTemplate="{TemplateBinding ContentTemplate}" Grid.ColumnSpan="2" Grid.Row="1" CanContentScroll="{TemplateBinding CanContentScroll}" CanHorizontallyScroll="False" CanVerticallyScroll="False"/>
                                        <ScrollBar x:Name="PART_VerticalScrollBar" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Grid.Column="2" Grid.Row="1" Maximum="{TemplateBinding ScrollableHeight}" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" Orientation="Vertical" ViewportSize="{TemplateBinding ViewportHeight}"/>
                                        <Grid Grid.Column="1" Grid.Row="2">
                                            <Grid.ColumnDefinitions>
                                                <ColumnDefinition Width="{Binding NonFrozenColumnsViewportHorizontalOffset, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type toolkit:DataGrid}}}"/>
                                                <ColumnDefinition Width="*"/>
                                            </Grid.ColumnDefinitions>
                                            <ScrollBar x:Name="PART_HorizontalScrollBar" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Grid.Column="1" Maximum="{TemplateBinding ScrollableWidth}" Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" Orientation="Horizontal" ViewportSize="{TemplateBinding ViewportWidth}"/>
                                        </Grid>
                                    </Grid>
                                </ControlTemplate>
                            </ScrollViewer.Template>
                            <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                        </ScrollViewer>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <Trigger Property="IsGrouping" Value="True">
                <Setter Property="ScrollViewer.CanContentScroll" Value="False"/>
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>
<Grid>
    <toolkit:DataGrid Name="dataGrid" 
                      ItemsSource="{Binding}"
                      CanUserResizeRows="False" 
                      SelectionMode="Extended" 
                      AutoGenerateColumns="True" Style="{DynamicResource DataGridStyle1}">
        <toolkit:DataGrid.RowHeaderTemplate>
            <DataTemplate>
                <Grid>
                    <CheckBox IsChecked="{
                        Binding Path=IsSelected, 
                        Mode=TwoWay, 
                        RelativeSource={RelativeSource FindAncestor, 
                        AncestorType={x:Type toolkit:DataGridRow}}}"
                        />
                </Grid>
            </DataTemplate>
        </toolkit:DataGrid.RowHeaderTemplate>
    </toolkit:DataGrid>
</Grid>

You can override that Button's Command to perform your own logic or even replace the button with a different control.

您可以覆盖该Button的Command来执行您自己的逻辑,甚至可以用不同的控件替换该按钮。