簡體   English   中英

樣式觸發器的WPF屬性目標

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM