【发布时间】:2011-02-18 13:30:05
【问题描述】:
是否可以禁用 WPF DataGrid 左上角的“全选”按钮?
【问题讨论】:
-
我不确定是否要禁用它,但我发现隐藏你的 RowHeaders 会隐藏它。 (给我带来了问题,因为我想隐藏 RowHeaders 但显示 SelectAll 按钮)
标签: c# wpf xaml datagrid user-controls
是否可以禁用 WPF DataGrid 左上角的“全选”按钮?
【问题讨论】:
标签: c# wpf xaml datagrid user-controls
DataGrid 中有一个属性HeadersVisibility。它有四个值 - All、Column、Row、None。
使用HeadersVisibility = All,您将获得全选按钮。
使用HeadersVisibility = Column,您将只获得列。不是 SelectAll Button 或 Row Headers 来选择完整的行。
使用HeadersVisibility = Row,您将只获得行标题来选择整行。不是 SelectAll 按钮或列。
使用HeadersVisibility = None,您将一无所获。所有标题都将被隐藏。
希望对你有帮助。
【讨论】:
在使用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 事件。
希望这会有所帮助!
【讨论】:
为 SelectAll 命令添加一个命令绑定,并在 CanExecute 中返回 false 以禁用全选按钮。
【讨论】:
如果您不需要在 DataGrid 中进行扩展选择(即切换到单个单元格选择),您可以设置:
<DataGrid SelectionMode="Single">
它还会禁用左上角的 SelectAll 按钮。
【讨论】:
基于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。
【讨论】:
我会更改 DataGrid 的 Control Template。
需要在模板内禁用此按钮。
这是DataGridControlTemplate:
<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。
【讨论】: