如何禁用 DataGrid 的“全选”按钮
Posted
技术标签:
【中文标题】如何禁用 DataGrid 的“全选”按钮【英文标题】:How to disable the 'Select All' button of a DataGrid 【发布时间】:2011-02-18 13:30:05 【问题描述】:是否可以禁用 WPF DataGrid 左上角的“全选”按钮?
【问题讨论】:
我不确定是否要禁用它,但我发现隐藏你的 RowHeaders 会隐藏它。 (给我带来了问题,因为我想隐藏 RowHeaders 但显示 SelectAll 按钮) 【参考方案1】:DataGrid
中有一个属性HeadersVisibility
。它有四个值 - All
、Column
、Row
、None
。
使用HeadersVisibility = All
,您将获得全选按钮。
使用HeadersVisibility = Column
,您将只获得列。不是 SelectAll Button 或 Row Headers 来选择完整的行。
使用HeadersVisibility = Row
,您将只获得行标题来选择整行。不是 SelectAll 按钮或列。
使用HeadersVisibility = None
,您将一无所获。所有标题都将被隐藏。
希望对你有帮助。
【讨论】:
【参考方案2】:在使用Snoop 分析我放在一起的测试应用程序的可视化树之后,我使用DataGrid_Loaded 事件提出了这个解决方案):
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;
可能有一个更优雅的仅限 XAML 的解决方案,但这是首先想到的,而且它似乎工作得很好(我显然也没有进行任何异常处理)。
注意:我没有尝试禁用/重新启用 DataGrid 以确保全选按钮保持禁用。如果它没有保持禁用状态,那么您可能还需要挂钩 DataGrid_IsEnabledChanged 事件。
希望这会有所帮助!
【讨论】:
这是一个糟糕的解决方案,并且很容易受到 xaml 构造中的修改的影响。如果您只想禁用按钮,请按照 Eben 的建议使用绑定到命令,或者如果您想隐藏按钮,请按照 Varun 的建议禁用显示。【参考方案3】:为 SelectAll 命令添加一个命令绑定,并在 CanExecute 中返回 false 以禁用全选按钮。
见:Event for Select All: WPF Datagrid
【讨论】:
【参考方案4】:如果您不需要在 DataGrid 中进行扩展选择(即切换到单个单元格选择),您可以设置:
<DataGrid SelectionMode="Single">
它还会禁用左上角的 SelectAll 按钮。
【讨论】:
【参考方案5】:基于this answer,您可以保留标题和选择模式。
在你的用户控件的资源里面放:
<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>
稍微多做一些工作,您可以添加一个工具提示来帮助用户发现 Ctrl 和 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>
有关行标题中的复选框,请参阅this post。
【讨论】:
【参考方案6】:我会更改 DataGrid 的 Control Templat
e。
需要在模板内禁用此按钮。
这是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>
手动禁用该按钮并将此ControlTemplate
分配给您的DataGrid
。
【讨论】:
以上是关于如何禁用 DataGrid 的“全选”按钮的主要内容,如果未能解决你的问题,请参考以下文章
WPF DataGrid“选择所有按钮”,后跟 Control-C