Search code examples
wpfdatagridwpfdatagridwpf-style

Border per column header


I want to create a table on wpf that each column header has a round corner this is what i got so far:

enter image description here

as you can see, i have the desired outcome with a little un desired outcome. the undesired out come is that the all data grid header itself (not the columns) is getting the same border, i need to make it transparent, how can i do that?

this is the part of the style:

<DataGrid.ColumnHeaderStyle>
    <Style TargetType="{x:Type DataGridColumnHeader}">
        <Setter Property="SeparatorBrush"  Value="Transparent"/>
        <Setter Property="Margin" Value="2"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>                                        
                        <Grid>
                            <Border CornerRadius="5 5 0 0" BorderThickness="1" BorderBrush="Black">
                                <TextBlock Text="{Binding }"/>
                            </Border>
                        </Grid>                                        
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</DataGrid.ColumnHeaderStyle>  

Solution

  • for some reasons, DataGrid has a blank DataGridColumnHeader in its template. that blank columns doesn't have DataContext value (null). So change border brush to transparent in a DataTrigger:

    <ControlTemplate>
        <Grid>
            <Border CornerRadius="5 5 0 0" BorderThickness="1" >
                <TextBlock Text="{Binding}"/>
                <Border.Style>
                    <Style TargetType="Border">
                        <Setter Property="BorderBrush" Value="Black"/>
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding}" Value="{x:Null}">
                                <Setter Property="BorderBrush" Value="Transparent"/>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </Border.Style>
            </Border>
        </Grid>
    </ControlTemplate>
    


    improved version, which uses ContentPresenter in header template and test Content in a trigger

    <ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
        <Grid>
            <Border CornerRadius="5 5 0 0" BorderThickness="1" >
                <ContentPresenter/>                                        
                <Border.Style>
                    <Style TargetType="Border">
                        <Setter Property="BorderBrush" Value="Black"/>
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding Path=Content, RelativeSource={RelativeSource TemplatedParent}}" Value="{x:Null}">
                                <Setter Property="BorderBrush" Value="Transparent"/>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </Border.Style>
            </Border>
        </Grid>
    </ControlTemplate>
    

    header is not necessary a text, e.g.:

    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding Path=Name}">
            <DataGridTextColumn.Header>
                <Border Background="Cyan">
                    <TextBlock Text="NAME" Margin="5"/>
                </Border>
            </DataGridTextColumn.Header>
        </DataGridTextColumn>
    </DataGrid.Columns>