我正在使用DataGrid上添加的“Tag”属性定义自定义DataGridTextColumn,如下所示
<local:DataGridTextColumn Binding="{Binding Path=Company}"
Header="Company"
Tag="String"
IsReadOnly="True" />
我已经定义了一些资源XAML来控制网格的渲染,但是我遇到了问题。我想在DataGridColumnHeader上呈现自定义ContextMenu,具体取决于使用触发器的“Tag”属性的值。但是,我找不到从样式中引用列“Tag”值的方法。我已经尝试过DataTriggers和常规触发器。
<Style TargetType="{x:Type DataGridColumnHeader}">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=local:DataGridTextColumn}, Path=Tag}" Value="String">
<Setter Property="ContextMenu" Value="{StaticResource ColumnHeaderContextMenuString}" />
</DataTrigger>
<Trigger Property="Tag" Value="Int">
<Setter Property="ContextMenu" Value="{StaticResource ColumnHeaderContextMenuInt}" />
</Trigger>
<Trigger Property="Tag" Value="DateTime">
<Setter Property="ContextMenu" Value="{StaticResource ColumnHeaderContextMenuDateTime}" />
</Trigger>
</Style.Triggers>
答案 0 :(得分:0)
首先,您必须从样式化的DataGridColumnHeader
元素到基础列。从那里,您可以深入了解Tag
。试试这个:
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Column.Tag}"
Value="String">
<Setter Property="ContextMenu"
Value="{StaticResource ColumnHeaderContextMenuString}" />
</DataTrigger>
但是如果您要使用标题样式,为什么不简单地为每个基础数据类型设置样式,并相应地设置每个列的HeaderStyle
?如果每个标题样式仅适用于单个数据类型,则不需要触发器。
答案 1 :(得分:0)
不要在设计时强制执行样式决策,方法是更改Tag属性,以便在运行时应用样式。为什么呢?
如果您可以在设计时更改标记,则可以使列标题符合特定样式。
目前还不清楚为什么需要 Rube Goldberg 设置设计时间风格的方式。
答案 2 :(得分:0)
DataGridColumnHeader基类型中没有标记属性。
使用:<Style TargetType="{x:Type local:DataGridTextColumn}">
和简单的触发器
答案 3 :(得分:0)
嘛!在你的工作中一切都很顺利,但解决问题需要一些概念:
关键概念:(可选阅读材料)'DataGridTextColumn'的标题属性处理其中的两种类型的数据,一种是Type:string,另一种是'Type:DataGridColumnHeader'。与许多其他Framework Properties相比,字符串类型值在编译时不会转换为其他类型。因此设置值Header =“Company”仍保留在sting数据类型中,并且设置ContextMenu属性意义较小。
有很多解决方案/方法可以解决这个问题,但我发布了接近你的方法的答案......
解决方案:正在设置样式,但设置标题属性如下:
<DataGridTextColumn x:Name="CompanyColumn" Width="*" Binding="{Binding Company}">
<DataGridTextColumn.Header>
<DataGridColumnHeader Content="Company" Tag="String"/>
</DataGridTextColumn.Header>
</DataGridTextColumn>
为了支持其他访问者,我发送完整的代码来理解这种方法。
<Window x:Class="AnswerNo1.SolutionA"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:System="clr-namespace:System;assembly=mscorlib"
Title="SolutionA" Height="250" Width="400">
<Window.Resources>
<ContextMenu x:Key="ColumnHeaderContextMenuString">
<MenuItem Header="_Sentence case."/>
<MenuItem Header="_lowercase"/>
<MenuItem Header="_UPPERCASE"/>
<MenuItem Header="_Capitalize Each Word"/>
<MenuItem Header="_tOGGLE cASE"/>
</ContextMenu>
<ContextMenu x:Key="ColumnHeaderContextMenuInt">
<MenuItem Header="Show _SUM"/>
<MenuItem Header="Show _Mean"/>
<MenuItem Header="Show Standard Deviation"/>
<MenuItem Header="Subtract All Form ..."/>
<MenuItem Header="Toggle Sign"/>
</ContextMenu>
<ContextMenu x:Key="ColumnHeaderContextMenuDateTime">
<MenuItem Header="Show Time Graph"/>
<MenuItem Header="Show Minimum Data"/>
<MenuItem Header="Show Maximum Data"/>
<MenuItem Header="Show Mode Day"/>
<MenuItem Header="Sort by day name"/>
</ContextMenu>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Style.Triggers>
<Trigger Property="Tag" Value="String">
<Setter Property="ContextMenu" Value="{StaticResource ColumnHeaderContextMenuString}" />
</Trigger>
<Trigger Property="Tag" Value="Int">
<Setter Property="ContextMenu" Value="{StaticResource ColumnHeaderContextMenuInt}" />
</Trigger>
<Trigger Property="Tag" Value="DateTime">
<Setter Property="ContextMenu" Value="{StaticResource ColumnHeaderContextMenuDateTime}" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<DataGrid x:Name="YourDataGrid" AutoGenerateColumns="False" Margin="3">
<DataGrid.Columns>
<DataGridTextColumn x:Name="CompanyColumn" Width="*" Binding="{Binding Company}">
<DataGridTextColumn.Header>
<DataGridColumnHeader Content="Company" Tag="String"/>
</DataGridTextColumn.Header>
</DataGridTextColumn>
<DataGridTextColumn x:Name="ReputationColumn" Width="*" Binding="{Binding Reputation}">
<DataGridTextColumn.Header>
<DataGridColumnHeader Content="Reputation" Tag="Int"/>
</DataGridTextColumn.Header>
</DataGridTextColumn>
<DataGridTextColumn x:Name="SetupDateColumn" Width="*" Binding="{Binding SetupDate}">
<DataGridTextColumn.Header>
<DataGridColumnHeader Content="Setup Date" Tag="DateTime"/>
</DataGridTextColumn.Header>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Label Content="Tag for 1st Column: "/>
<ComboBox Grid.Column="1" SelectedItem="{Binding Header.Tag, ElementName=CompanyColumn}" >
<System:String>String</System:String>
<System:String>Int</System:String>
<System:String>DateTime</System:String>
</ComboBox>
</Grid>
</Grid>
答案 4 :(得分:0)
我最终不得不为此编写非XAML解决方案。这是获得具有内容感知上下文菜单的可重用DataGrid的唯一方法。每次添加网格时,其他解决方案都需要大量的配置(加上我无法让它们工作)。