wpf - 如何在 WPF DataGrid 的 RowHeader 的“列标题”上获取单击事件
问题描述
我有一个带有 RowHeaders 的 DataGrid。这些 RowHeaders 显示在,我称之为网格的第一列。所有“数据”列都有一个标题,其中包含列的名称。包含行标题的“第一列”没有这样的“标题”。是否可以在该“标题”上捕获点击事件?为了清楚我的意思是什么“标题”,这里有一张图片:
编辑:
这是我的DataGrid
定义,包括来自@EldHasp答案的代码
<DataGrid Name="TenantsGrid"
Style="{StaticResource DataGridStyle}"
d:ItemsSource="{Binding TenantGridDataSource}"
AutoGenerateColumns="False"
CanUserResizeRows="False"
SelectionMode="Single"
IsReadOnly="True"
SelectedItem="{Binding SelectedTenant}" Margin="10,0,11,10">
<FrameworkElement.Resources>
<Style x:Key="{ComponentResourceKey ResourceId=DataGridSelectAllButtonStyle, TypeInTargetAssembly={x:Type DataGrid}}"
TargetType="{x:Type Button}"
BasedOn="{StaticResource {ComponentResourceKey ResourceId=DataGridSelectAllButtonStyle, TypeInTargetAssembly={x:Type DataGrid}}}">
<EventSetter Event="Click" Handler="OnClickSelectAll"/>
</Style>
</FrameworkElement.Resources>
<DataGrid.Columns>
<DataGridTextColumn Header="Nachname" Width="Auto" Binding="{Binding LastName}" CanUserSort="True"/>
<DataGridTextColumn Header="Vorname" Width="Auto" Binding="{Binding FirstName}" CanUserSort="True"/>
<DataGridTextColumn Header="eMail" Width="Auto" Binding="{Binding EMail}" CanUserSort="False"/>
<DataGridTextColumn Header="Telefon" Width="Auto" Binding="{Binding PhoneNumber}" CanUserSort="False"/>
<DataGridTextColumn Header="Notizen" Width="*" Binding="{Binding Notes}" CanUserSort="False"/>
<DataGridCheckBoxColumn Width="Auto" Binding="{Binding Flagged}" CanUserSort="False">
<DataGridCheckBoxColumn.Header>
<TextBlock Text="M" ToolTip="Markiert - Auf Notizen achten!" />
</DataGridCheckBoxColumn.Header>
</DataGridCheckBoxColumn>
<DataGridCheckBoxColumn Width="Auto" Binding="{Binding Blocked}" CanUserSort="False">
<DataGridCheckBoxColumn.Header>
<TextBlock Text="B" ToolTip="Blockiert - Keine weitere Buchung annehmen!" />
</DataGridCheckBoxColumn.Header>
</DataGridCheckBoxColumn>
</DataGrid.Columns>
<DataGrid.ColumnHeaderStyle>
<Style TargetType="DataGridColumnHeader">
<EventSetter Event="Click" Handler="OnColumnHeaderClicked"/>
</Style>
</DataGrid.ColumnHeaderStyle>
<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<DataTrigger Binding="{Binding Flagged}" Value="True">
<Setter Property="Background" Value="#F1F5E4"/>
</DataTrigger>
<DataTrigger Binding="{Binding Blocked}" Value="True">
<Setter Property="Background" Value="#DDD5C3"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
</DataGrid>
DataGridStyle
是:
<Style x:Key="DataGridStyle" TargetType="DataGrid">
<Setter Property="RowHeaderStyle" Value="{DynamicResource GridRowHeaderStyle}"/>
</Style>
<Style x:Key="GridRowHeaderStyle" TargetType="DataGridRowHeader">
<Setter Property="Width" Value="20"/>
<Style.Triggers>
<Trigger Property="IsRowSelected" Value="True">
<Setter Property="FontFamily" Value="Segoe UI"/>
<Setter Property="FontSize" Value="12"/>
<Setter Property="Foreground" Value="Gray"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="5 0"/>
<Setter Property="Content" Value="●"/>
</Trigger>
</Style.Triggers>
</Style>
解决方案
这是默认的 DataGrid 模板:
<Style x:Key="{ComponentResourceKey ResourceId=DataGridSelectAllButtonStyle, TypeInTargetAssembly={x:Type DataGrid}}" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Rectangle x:Name="Border" Fill="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" SnapsToDevicePixels="True"/>
<Polygon x:Name="Arrow" Fill="Black" HorizontalAlignment="Right" Margin="8,8,3,3" Opacity="0.15" Points="0,10 10,10 10,0" Stretch="Uniform" VerticalAlignment="Bottom"/>
</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>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type 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="ScrollViewer.PanningMode" Value="Both"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<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>
</Setter.Value>
</Setter>
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsGrouping" Value="true"/>
<Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</MultiTrigger>
</Style.Triggers>
</Style>
左上角(行标题上方)的按钮在此行中定义:
<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}}}"/>
因此,您可以通过以下方式添加处理:
由于此按钮使用 DynamicResource 接收样式,因此您可以通过在其中设置所需的处理程序来覆盖或补充此样式。
您可以为 SelectedAll 命令设置 CommandBinding。
演示两种方式的示例:
<DataGrid>
<UIElement.CommandBindings>
<CommandBinding Command="{x:Static DataGrid.SelectAllCommand}"
CanExecute="OnSelectAllCanExecute"
Executed="OnSelectAllExecute"/>
</UIElement.CommandBindings>
<FrameworkElement.Resources>
<Style x:Key="{ComponentResourceKey ResourceId=DataGridSelectAllButtonStyle, TypeInTargetAssembly={x:Type DataGrid}}"
TargetType="{x:Type Button}"
BasedOn="{StaticResource {ComponentResourceKey ResourceId=DataGridSelectAllButtonStyle, TypeInTargetAssembly={x:Type DataGrid}}}">
<EventSetter Event="Click" Handler="OnClickSelectAll"/>
</Style>
</FrameworkElement.Resources>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Mode=OneWay}" Header="Letter"/>
</DataGrid.Columns>
<DataGrid.RowHeaderTemplate>
<DataTemplate>
<TextBlock Text="123456"/>
</DataTemplate>
</DataGrid.RowHeaderTemplate>
<DataGrid.ItemsSource>
<sys:String>123456</sys:String>
</DataGrid.ItemsSource>
</DataGrid>
private void OnSelectAllCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
private void OnSelectAllExecute(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("The \"Select all\" command was invoked.");
}
private void OnClickSelectAll(object sender, RoutedEventArgs e)
{
MessageBox.Show("Was clicked \"Select all\".");
}
推荐阅读
- cucumber - 错误:“from”参数必须是字符串类型。收到未定义
- maven - 未在本地复制的依赖项(depclean 警告)
- wpf - 如何从选项卡控件中删除白色边框?
- python - 仅使用 FBProphet 进行逐年预测的问题
- docker - 使用 DockerFile 构建 Git 子树
- http-proxy - Sencha cmd 6.5 不接受代理设置
- file-locking - 如何使用flock创建文件锁并稍后解锁?
- cmd - 如何使用命令提示符运行共享驱动器上可用的 exe
- java - 我在 Netbeans IDE 上运行 JSP 和 Servlet 时遇到问题
- python - python中pdf文件中图像的文本识别