![](/img/trans.png)
[英]Using a trigger property on a different type to the setter property on WPF style
[英]WPF Property Target for Style Trigger
我正在定義一個自定義DataGridTextColumn,並在DataGrid上添加了“ Tag”屬性,如下所示
<local:DataGridTextColumn Binding="{Binding Path=Company}"
Header="Company"
Tag="String"
IsReadOnly="True" />
我已經定義了一些資源XAML來控制網格的呈現,但是我有一個問題。 我想根據使用觸發器的“ Tag”屬性的值在DataGridColumnHeader上呈現自定義ContextMenu。 但是,我找不到從樣式中引用列“ 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>
首先,您必須從樣式化的DataGridColumnHeader
元素獲取基礎列。 從那里,您可以深入到Tag
。 嘗試這個:
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Column.Tag}"
Value="String">
<Setter Property="ContextMenu"
Value="{StaticResource ColumnHeaderContextMenuString}" />
</DataTrigger>
但是,如果要使用標題樣式,為什么不簡單地為每種基礎數據類型使用樣式,並相應地設置各列的HeaderStyle
? 如果每種標題樣式僅適用於單個數據類型,則不需要觸發器。
不要在設計時通過更改Tag屬性來強制樣式決定,以在運行時應用樣式。 為什么?
如果可以在設計時更改標簽,則可以使列標題遵循特定樣式。
目前尚不清楚為什么需要使用Rube Goldberg設置設計時間樣式的方法。
DataGridColumnHeader基本類型中沒有Tag屬性。 使用: <Style TargetType="{x:Type local:DataGridTextColumn}">
和簡單的觸發器
好! 您的工作一切都很好,但是需要一些概念來解決問題:
關鍵概念:(可選的閱讀材料)“ DataGridTextColumn”的Header屬性處理其中的兩種數據,一種是Type:string,另一種是“ Type:DataGridColumnHeader”。 與許多其他Framework屬性相比,字符串類型值在編譯時不會轉換為其他類型。 因此,設置值Header =“ Company”保留在字符串數據類型中,設置ContextMenu屬性的意義較小。
有很多解決方案/方法可以解決此問題,但是我發布的答案很接近您的方法……。
解決方案:設置樣式,但設置header屬性如下:
<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>
我最終不得不為此編寫一個非XAML解決方案。 這是獲得具有內容感知上下文菜單的可重用DataGrid的唯一方法。 其他解決方案在每次添加網格時都需要大量的配置(而且我無法使它們正常工作)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.