我正在定义一个自定义DataGridTextColumn,在DataGrid上添加了“Tag”属性,如下所示
<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>
5 回答
不要在设计时强制执行样式决策,方法是更改Tag属性,以便在运行时应用样式 . 为什么?
如果您可以在设计时更改标记,则可以使列 Headers 符合特定样式 .
目前还不清楚为什么需要Rube Goldberg设定设计时间风格的方法 .
首先,您必须从样式化的
DataGridColumnHeader
元素到基础列 . 从那里,您可以深入了解Tag
. 试试这个:但是如果你相应的话're going to use header styles, why not simply have a style for each underlying data type, and set each column'?如果每个 Headers 样式仅适用于单个数据类型,则不需要触发器 .
DataGridColumnHeader基类型中没有 Tag 属性 . 使用:
<Style TargetType="{x:Type local:DataGridTextColumn}">
和简单的触发器好!在你的工作中一切都很顺利,但解决问题需要一些概念:
Key Concept: (可选阅读材料)'DataGridTextColumn'的头属性处理其中的两种类型的数据,一种是Type:string,另一种是'Type:DataGridColumnHeader' . 与许多其他Framework Properties相比,字符串类型值在编译时不会转换为其他类型 . 因此设置值Header = "Company"保留在sting数据类型中,并且设置ContextMenu属性意味着更少 .
有很多解决方案/方法可以解决这个问题,但我发布了接近你的方法的答案....
Solution: 设置样式,但设置 Headers 属性如下:
为了支持其他访问者,我发送完整的代码来理解这种方法 .
我最终不得不为此编写非XAML解决方案 . 这是获得具有内容感知上下文菜单的可重用DataGrid的唯一方法 . 每次添加网格时,其他解决方案都需要大量的配置(加上我无法让它们工作) .