Event for Select All: WPF Datagrid

2020-02-10 06:31发布

I am using WPF data-grid. In data-grid user have column-headers and row-headers.

When column-headers and row-headers both of them are visible, in the top left corner we have one small square section available. (cross section in the top left corner where the column and row headers meet.) when we click on that it selects all the cells within data-grid. Is there any event for that? If not how can trap that event. Please guide me.

Do let me know if you need any other information regarding this problem.

Regards, Priyank

3条回答
不美不萌又怎样
2楼-- · 2020-02-10 06:43

It is not quite a nice solution, but you can handle an event like "SelectionChanged" and check if the number of selected items equals the number of items in your data source

查看更多
▲ chillily
3楼-- · 2020-02-10 06:49

I prefer to avoid using a code behind in views, so I've done it this way: enter image description here

enter image description here

It is CheckBox on top left corner that select/unselect all.

The solution are built from 2 parts: Attached Properties and especial XAML structure:

1). Attached properties:

public class DataGridSelectAllBehavior
{
    public static bool GetValue(DependencyObject obj)
    {
        return (bool)obj.GetValue(ValueProperty);
    }

    public static void SetValue(DependencyObject obj, bool value)
    {
        obj.SetValue(ValueProperty, value);
    }
    public static readonly DependencyProperty ValueProperty =
        DependencyProperty.RegisterAttached("Value", typeof(bool), typeof(DataGridSelectAllBehavior), new PropertyMetadata(false,
            (o, e) =>
            {
                var dg = DataGridSelectAllBehavior.GetDataGrid(o);
                CheckBox checkBox = o as CheckBox;

                if (checkBox.IsChecked == true)
                {
                    dg.SelectAll();
                }
                else
                {
                    dg.UnselectAll();
                }

            }));


    public static DataGrid GetDataGrid(DependencyObject obj)
    {
        return (DataGrid)obj.GetValue(DataGridProperty);
    }

    public static void SetDataGrid(DependencyObject obj, DataGrid value)
    {
        obj.SetValue(DataGridProperty, value);
    }

    public static readonly DependencyProperty DataGridProperty =
        DependencyProperty.RegisterAttached("DataGrid", typeof(DataGrid), typeof(DataGridSelectAllBehavior), new PropertyMetadata(null));

}

2) XAML:

 <DataGrid ItemsSource="{Binding PendingChanges}"
          AutoGenerateColumns="False"
          IsReadOnly="True"
          SelectionMode="Extended">
    <i:Interaction.Behaviors>
        <behaviors:MultiSelectGridSelectedItemsBehavior SelectedItems="{Binding SelectedPendingChanges, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
    </i:Interaction.Behaviors>
    <DataGrid.Columns>
        <DataGridCheckBoxColumn Binding="{Binding Path=IsSelected,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow}}}">
            <DataGridCheckBoxColumn.HeaderTemplate>
                <DataTemplate>
                    <CheckBox 
                              behaviors:DataGridSelectAllBehavior.Value="{Binding IsChecked,RelativeSource={RelativeSource Self}}"
                              behaviors:DataGridSelectAllBehavior.DataGrid="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGrid}}}"/>
                </DataTemplate>
            </DataGridCheckBoxColumn.HeaderTemplate>
        </DataGridCheckBoxColumn>
        <DataGridTextColumn Header="Name"
                            Width="Auto"
                            Binding="{Binding Name, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" />
        <DataGridTextColumn Header="State"
                            Width="Auto"
                            Binding="{Binding State, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" />
        <DataGridTextColumn Header="Folder"
                            Width="*"
                            Binding="{Binding ParentFolderPath, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" />
    </DataGrid.Columns>
</DataGrid>
查看更多
家丑人穷心不美
4楼-- · 2020-02-10 07:04

The datagrid handles the routed command ApplicationCommand.SelectAll, so if the grid has focus and your press Ctrl-A, or you click the corner button, all cells are selected. You can handle this command yourself by adding a CommandBinding in xaml:

<DataGrid x:Name="dataGrid" .../>
    <DataGrid.CommandBindings>
        <CommandBinding Command="ApplicationCommands.SelectAll" Executed="SelectAll_Executed"/>
    </DataGrid.CommandBindings>

Or you can add the command binding in code:

public MyControl(){
    InitializeComponent();
    ...
    dataGrid.CommandBindings.Add(new CommandBinding(ApplicationCommands.SelectAll, SelectAll_Executed));
}

However, there can only be a single handler for a routed command, so by default adding this handler this will prevent select all from working in the datagrid. In your handler you need therefore to call SelectAll.

private void SelectAll_Executed(object sender, ExecutedRoutedEventArgs e)
{
    Debug.WriteLine("Executed");
    dataGrid.SelectAll();
}
查看更多
登录 后发表回答