开发者

How do I style a DataGridHeader based on information from the DataGridColumn?

开发者 https://www.devze.com 2023-02-15 01:36 出处:网络
I have a DataGrid, and in that grid, some of the columns are marked Read only: <DataGrid AutoGenerateColumns=\"False\">

I have a DataGrid, and in that grid, some of the columns are marked Read only:

<DataGrid AutoGenerateColumns="False">
    <DataGrid.Columns>
        <!-- this column is read only -->
        <DataGridTextCo开发者_JAVA技巧lumn 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>

I want that "Name" column to be visually distinguishable by the header that it is editable, when the other two columns are not. I can't seeem to get to the IsReadOnly property of the DataGridColumn, though.

I'm effectively trying to do something like:

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

From this question: Binding Visible property of a DataGridColumn in WPF DataGrid, it appears that DataGridColumn isn't a framework element, so i can't find it using RelativeSource AncestorType=DataGridColumn. That poster says they used a static resource to find it, but doesn't explain what/how (and several answers there are questions of how the poster solved it)

This question: How to get DataGridColumnHeader from DataGridColumn?, looks like i could get to it from code, but i'd really like this to just be xaml and generic to apply to any data grid.

Is there something simple i'm overlooking?


Answering my own question, in case anyone else runs into this...

It turns out there isn't a lot you can do here from XAML, because of some of the things mentioned in the question. The simplest thing i could do from XAML was make the headers of the editable columns bold to differentiate them from the rest of the columns.

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

You can do more complicated things, like:

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

But you end up getting some really wierd behaviors, where the sort icon disappears, or other wierd things. If you want to change the column headers and make it look consistant, you pretty much have to restyle the whole datagrid and all of its headers through styles and templates.


DataGridColumnHeader has property Column, which has the property 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>

In your example you could do:

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

0

精彩评论

暂无评论...
验证码 换一张
取 消