Special Gridline Style for Only One Column

2019-08-08 15:55发布

问题:

How would I set a custom grid line style on just one column of a DataGrid? In particular, I'd like one column to have a double line as its left border.

Example:

| Col1 | Col2 || Col3 (w/ Double Left Border) |

Thank you,
Ben

回答1:

It depends on where you want this double line. The vertical GridLines is drawn in OnRender for DataGridCell and the horizontal GridLines is drawn in OnRender for DataGridCellsPresenter. The border for the DataGridColumnHeader is more complicated however. It's a Rectangle that's drawn in the RenderTheme method in DataGridHeaderBorder and I don't think that there is a direct way to change its width without re-templating the entire DataGridColumnHeader. Also, the border thickness for the Headers are twice as thick as the Cells in the DataGrid to begin with (1px vs 2px), because the Headers draw their Separators on both sides.

So, to get double line thickness which just affects the Cells you can add a special DataGridCell style where you want this to apply. All this cellstyle does is to draw a 1px border to the left in the same colour as the GridLines. It'll look something like this

<DataGrid ...
          HorizontalGridLinesBrush="Black">
    <DataGrid.Resources>
        <Style x:Key="DoubleLeftBorderCell" TargetType="DataGridCell">
            <Setter Property="BorderThickness" Value="1,0,0,0"/>
            <Setter Property="BorderBrush" Value="{Binding ElementName=dataGrid, Path=HorizontalGridLinesBrush}"/>
        </Style>
    </DataGrid.Resources>
    <DataGrid.Columns>
        <DataGridTextColumn Header="Double left Border"
                            CellStyle="{StaticResource DoubleLeftBorderCell}"
                            Binding="{Binding TextProperty}"/>
    </DataGrid.Columns>
</DataGrid>

There is no mouseover effect or anything on the cells to worry about. If you do something similar for a DataGridColumnHeader however, you'll lose the sorting arrows, mouseover effect, mousedown effect etc. so a you'll have to create an entire template for it



回答2:

Here's what I ended up doing:

<DataGridTextColumn Header="Header Name">
    <DataGridTextColumn.CellStyle>
        <Style TargetType="{x:Type DataGridCell}">
            <Setter Property="Margin" Value="1 0 0 0" />
            <Setter Property="BorderThickness" Value="1 0 0 0" />
            <Setter Property="BorderBrush" Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=HorizontalGridLinesBrush}" />
        </Style>
    </DataGridTextColumn.CellStyle>
</DataGridTextColumn>

This is based on Meleak's answer but with the addition of margin (to create the double-line effect) and using a RelativeSource for the border brush, removing the need for the DataGrid to have a x:Name.