如何根据DataGridColumn中的信息设置DataGridHeader的样式?

时间:2011-03-04 18:42:58

标签: wpf datagrid columnheader

我有一个DataGrid,在该网格中,有些列标记为只读:

<DataGrid AutoGenerateColumns="False">
    <DataGrid.Columns>
        <!-- this column is read only -->
        <DataGridTextColumn Header="Column A" Binding="{Binding Path=PropertyA}" IsReadOnly="True" />

        <!-- this column is EDITABLE -->
        <DataGridTextColumn Header="Name" Binding="{Binding Path=Name,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" IsReadOnly="False" />

        <!-- this column is read only -->
        <DataGridTextColumn Header="Column C" Binding="{Binding Path=PropertyC}" IsReadOnly="True" />
    </DataGrid.Columns>

我希望“名称”列可以通过可编辑的标题在视觉上区分,而其他两列则不可编辑。但是,我无法看到要访问DataGridColumn的IsReadOnly属性。

我正在尝试做类似的事情:

<DataGrid.ColumnHeaderStyle>
     <Style TargetType="DataGridColumnHeader" >
         <Style.Triggers>
             <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=DataGridColumn}, Path=IsReadOnly}" Value="false">
                 <Setter Property="Background" Value="Azure" />
              </DataTrigger>
          </Style.Triggers>
      </Style>                                  
</DataGrid.ColumnHeaderStyle>

从这个问题: Binding Visible property of a DataGridColumn in WPF DataGrid,似乎DataGridColumn不是框架元素,因此我无法使用RelativeSource AncestorType=DataGridColumn找到它。那张海报说他们使用静态资源来找到它,但没有解释什么/如何(以及有关海报如何解决问题的几个答案)

这个问题:How to get DataGridColumnHeader from DataGridColumn?,看起来我可以从代码中找到它,但我真的希望这只是xaml和generic适用于任何数据网格。< / p>

我有什么简单的东西可以忽略吗?

2 个答案:

答案 0 :(得分:1)

回答我自己的问题,万一其他人遇到这个......

事实证明,由于问题中提到的一些事情,你可以从XAML那里做很多事情 。我可以从XAML做的最简单的事情是将可编辑列的标题加粗,以区别于其他列。

<DataGridTextColumn Header="Editable Column" Binding="{Binding Path=EditableProperty,Mode=TwoWay}" IsReadOnly="False" Width="150">
    <DataGridTextColumn.HeaderStyle>
        <Style TargetType="DataGridColumnHeader">
            <Setter Property="FontWeight" Value="Bold"/>
            <Setter Property="ToolTip" Value="You can modify the values of this column."/>
        </Style>
    </DataGridTextColumn.HeaderStyle>
</DataGridTextColumn>

可以做更复杂的事情,比如:

<Style.Triggers>
    <Trigger Property="IsMouseOver" Value="False">
        <Trigger.Setters>
            <Setter Property="Background">
                <Setter.Value>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="{DynamicResource ControlLightColor}" Offset="0" />
                        <GradientStop Color="LightSteelBlue" Offset="1" />
                    </LinearGradientBrush>
                </Setter.Value>
            </Setter>
        </Trigger.Setters>
    </Trigger>
</Style.Triggers>  

但是你最终会得到一些非常奇怪的行为,排序图标消失,或其他奇怪的事情。如果您想要更改列标题并使其看起来一致,那么您几乎必须通过样式和模板重新设置整个数据网格及其所有标题。

答案 1 :(得分:0)

DataGridColumnHeader具有Column属性,该属性具有IsReadOnly

属性
<Label  Content="(read only)" DockPanel.Dock="Bottom">
<Label.Style>
    <Style TargetType="Label">
        <Setter Property="Visibility" Value="Collapsed"></Setter>
        <Style.Triggers>
            <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=DataGridColumnHeader},Path=Column.IsReadOnly}" Value="True">
                <Setter Property="Visibility" Value="Visible"></Setter>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</Label.Style>

在您的示例中,您可以执行以下操作:

<DataGrid.ColumnHeaderStyle>
 <Style TargetType="DataGridColumnHeader" >
     <Style.Triggers>
         <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=DataGridColumnHeader}, Path=Column.IsReadOnly}" Value="False">
             <Setter Property="Background" Value="Azure" />
          </DataTrigger>
      </Style.Triggers>
  </Style>