Is it possible to disable the "Select all" button in the upper left corner of the WPF DataGrid?
问题:
回答1:
After using Snoop to analyze the Visual Tree of a test app I put together, I came up with this solution using the DataGrid_Loaded event):
private void TheGrid_Loaded(object sender, RoutedEventArgs e) {
var dataGrid = (DataGrid)sender;
var border = (Border)VisualTreeHelper.GetChild(dataGrid, 0);
var scrollViewer = (ScrollViewer)VisualTreeHelper.GetChild(border, 0);
var grid = (Grid)VisualTreeHelper.GetChild(scrollViewer, 0);
var button = (Button)VisualTreeHelper.GetChild(grid, 0);
button.IsEnabled = false;
}
There may be a more elegant XAML only solution out there, but this is what came to mind first, and it seems to work well enough (I'm obviously not doing any Exception handling either).
Note: I haven't played around with disabling/re-enabling the DataGrid to make sure that the select all button stays disabled. If it doesn't stay disabled, then you may want to also hook into the DataGrid_IsEnabledChanged event.
Hope this helps!!
回答2:
There is a Property HeadersVisibility
in DataGrid
. It has four values - All
, Column
, Row
, None
.
With HeadersVisibility = All
, you will get the SelectAll Button.
With HeadersVisibility = Column
, you will get only Columns. Not the SelectAll Button or Row Headers to select a complete row.
With HeadersVisibility = Row
, you will get only Row headers to select whole row. Not the SelectAll Button or Columns.
With HeadersVisibility = None
, you will get nothing. All the headers will be hidden.
I hope this helps you.
回答3:
Add a commandbinding to the SelectAll Command and return false in the CanExecute to disable the selectall button.
see: Event for Select All: WPF Datagrid
回答4:
I would change the Control Templat
e of DataGrid.
Needs to disable this button inside of template.
This is DataGrid
ControlTemplate
:
<ControlTemplate TargetType="{x:Type DataGrid}">
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
Padding="{TemplateBinding Padding}"
SnapsToDevicePixels="True">
<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 DataGrid.SelectAllCommand}"
Focusable="false"
Style="{DynamicResource {ComponentResourceKey ResourceId=DataGridSelectAllButtonStyle, TypeInTargetAssembly={x:Type DataGrid}}}"
Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.All}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
Width="{Binding CellsPanelHorizontalOffset, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
<DataGridColumnHeadersPresenter x:Name="PART_ColumnHeadersPresenter"
Grid.Column="1"
Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.Column}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter"
CanContentScroll="{TemplateBinding CanContentScroll}"
Grid.ColumnSpan="2"
Grid.Row="1" />
<ScrollBar x:Name="PART_VerticalScrollBar"
Grid.Column="2"
Maximum="{TemplateBinding ScrollableHeight}"
Orientation="Vertical"
Grid.Row="1"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"
Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"
ViewportSize="{TemplateBinding ViewportHeight}" />
<Grid Grid.Column="1"
Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding NonFrozenColumnsViewportHorizontalOffset, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ScrollBar x:Name="PART_HorizontalScrollBar"
Grid.Column="1"
Maximum="{TemplateBinding ScrollableWidth}"
Orientation="Horizontal"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"
Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"
ViewportSize="{TemplateBinding ViewportWidth}" />
</Grid>
</Grid>
</ControlTemplate>
</ScrollViewer.Template>
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
</ControlTemplate>
Disable the button it manually and assign this ControlTemplate
to your DataGrid
.
回答5:
If you don't need extended selection in your DataGrid (i.e. switch to single cell selection), you may set:
<DataGrid SelectionMode="Single">
It disables also SelectAll button in top-left corner.
回答6:
Based on this answer, you can keep your headers and selection mode.
Inside the resources of your user control put :
<Style x:Key="{ComponentResourceKey ResourceId=DataGridSelectAllButtonStyle, TypeInTargetAssembly={x:Type DataGrid}}"
TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<!-- an empty ControlTemplate is fine -->
<ControlTemplate TargetType="{x:Type Button}" />
</Setter.Value>
</Setter>
</Style>
With a little bit of more work, you can add a ToolTip to help the user to discover Ctrl and Shift.
<Style x:Key="{ComponentResourceKey ResourceId=DataGridSelectAllButtonStyle, TypeInTargetAssembly={x:Type DataGrid}}"
TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<!-- an empty ControlTemplate is fine -->
<ControlTemplate TargetType="{x:Type Button}">
<DockPanel HorizontalAlignment="Center"
IsHitTestVisible="False"
VerticalAlignment="Center">
<TextBlock FontSize="18"
FontWeight="ExtraBlack"
Text="ⓘ"
TextAlignment="Center"
ToolTip="{StaticResource DataGridHowTo}" />
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
For the checkbox in the row headers see this post.