首页 文章

样式触发器的WPF属性目标

提问于
浏览
1

我正在定义一个自定义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 回答

  • 0

    不要在设计时强制执行样式决策,方法是更改Tag属性,以便在运行时应用样式 . 为什么?

    如果您可以在设计时更改标记,则可以使列 Headers 符合特定样式 .

    目前还不清楚为什么需要Rube Goldberg设定设计时间风格的方法 .

  • 0

    首先,您必须从样式化的 DataGridColumnHeader 元素到基础列 . 从那里,您可以深入了解 Tag . 试试这个:

    <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Column.Tag}" 
                 Value="String">
        <Setter Property="ContextMenu"
                Value="{StaticResource ColumnHeaderContextMenuString}" />
    </DataTrigger>
    

    但是如果你相应的话're going to use header styles, why not simply have a style for each underlying data type, and set each column'?如果每个 Headers 样式仅适用于单个数据类型,则不需要触发器 .

  • 0

    DataGridColumnHeader基类型中没有 Tag 属性 . 使用: <Style TargetType="{x:Type local:DataGridTextColumn}"> 和简单的触发器

  • 0

    好!在你的工作中一切都很顺利,但解决问题需要一些概念:

    Key Concept: (可选阅读材料)'DataGridTextColumn'的头属性处理其中的两种类型的数据,一种是Type:string,另一种是'Type:DataGridColumnHeader' . 与许多其他Framework Properties相比,字符串类型值在编译时不会转换为其他类型 . 因此设置值Header = "Company"保留在sting数据类型中,并且设置ContextMenu属性意味着更少 .

    有很多解决方案/方法可以解决这个问题,但我发布了接近你的方法的答案....

    Solution: 设置样式,但设置 Headers 属性如下:

    <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>
    
  • 0

    我最终不得不为此编写非XAML解决方案 . 这是获得具有内容感知上下文菜单的可重用DataGrid的唯一方法 . 每次添加网格时,其他解决方案都需要大量的配置(加上我无法让它们工作) .

相关问题