WPF - How to create a style that applies styles to child types

styles, tablecell, wpf, xaml

Solution

Update based on your comment

Based on your comment, I believe your problem could be easily solved using `Style` inheritance. Below is an example of using 2 different Cell Styles on different TableRowGroups:

<Table>
    <Table.Resources>

        <Style x:Key="HeaderCellStyle" TargetType="{x:Type TableCell}">
            <Setter Property="BorderThickness" Value="0,1,0,1" />
            <Setter Property="BorderBrush" Value="Black" />
            <Setter Property="TextAlignment" Value="Center" />
            <Setter Property="FontStyle" Value="Italic" />
            <Setter Property="Padding" Value="5" />
        </Style>

        <Style x:Key="FooterCellStyle" BasedOn="{StaticResource HeaderCellStyle}" TargetType="{x:Type TableCell}">
            <Setter Property="Background" Value="AliceBlue" />
            <Setter Property="TextAlignment" Value="Right" />
            <Setter Property="FontWeight" Value="Bold" />
        </Style>

        <Style x:Key="HeaderTableRowGroupStyle" TargetType="{x:Type TableRowGroup}">
            <Style.Resources>
                <Style BasedOn="{StaticResource HeaderCellStyle}" TargetType="{x:Type TableCell}" />
            </Style.Resources>
        </Style>

        <Style x:Key="FooterTableRowGroupStyle" TargetType="{x:Type TableRowGroup}">
            <Style.Resources>
                <Style BasedOn="{StaticResource FooterCellStyle}" TargetType="{x:Type TableCell}" />
            </Style.Resources>
        </Style>

    </Table.Resources>
    <Table.Columns>
        <TableColumn />
        <TableColumn />
        <TableColumn />
        <TableColumn />
    </Table.Columns>

    <!--  This TableRowGroup hosts a header row for the table.  -->
    <TableRowGroup Style="{StaticResource HeaderTableRowGroupStyle}">
        <TableRow>
            <TableCell />
            <TableCell>
                <Paragraph>Gizmos</Paragraph>
            </TableCell>
            <TableCell>
                <Paragraph>Thingamajigs</Paragraph>
            </TableCell>
            <TableCell>
                <Paragraph>Doohickies</Paragraph>
            </TableCell>
        </TableRow>
    </TableRowGroup>

    <!--  This TableRowGroup hosts the main data rows for the table.  -->
    <TableRowGroup>
        <TableRow>
            <TableCell>
                <Paragraph>Blue</Paragraph>
            </TableCell>
            <TableCell>
                <Paragraph>1</Paragraph>
            </TableCell>
            <TableCell>
                <Paragraph>2</Paragraph>
            </TableCell>
            <TableCell>
                <Paragraph>3</Paragraph>
            </TableCell>
        </TableRow>
        <TableRow>
            <TableCell>
                <Paragraph>Red</Paragraph>
            </TableCell>
            <TableCell>
                <Paragraph>1</Paragraph>
            </TableCell>
            <TableCell>
                <Paragraph>2</Paragraph>
            </TableCell>
            <TableCell>
                <Paragraph>3</Paragraph>
            </TableCell>
        </TableRow>
        <TableRow>
            <TableCell>
                <Paragraph>Green</Paragraph>
            </TableCell>
            <TableCell>
                <Paragraph>1</Paragraph>
            </TableCell>
            <TableCell>
                <Paragraph>2</Paragraph>
            </TableCell>
            <TableCell>
                <Paragraph>3</Paragraph>
            </TableCell>
        </TableRow>
    </TableRowGroup>

    <!--  This TableRowGroup hosts a footer row for the table.  -->
    <TableRowGroup Style="{StaticResource FooterTableRowGroupStyle}">
        <TableRow>
            <TableCell>
                <Paragraph>Totals</Paragraph>
            </TableCell>
            <TableCell>
                <Paragraph>3</Paragraph>
            </TableCell>
            <TableCell>
                <Paragraph>6</Paragraph>
            </TableCell>
            <TableCell>
                <Paragraph>9</Paragraph>
            </TableCell>
        </TableRow>
    </TableRowGroup>
</Table>

Whenever you want to define a general `Style` that will target all of the elements of a certain type, you must not specify a Key for that style. Try removing x:Key from the Style and everything should work properly, like this:

<Table.Resources>
    <Style TargetType="{x:Type TableRowGroup}">
        <Setter Property="FontWeight" Value="Normal"/>
        <Setter Property="FontSize" Value="12"/>
        <Setter Property="TableCell.BorderThickness" Value="0,1,0,1" />
        <Setter Property="TableCell.BorderBrush" Value="Black" />
    </Style>
</Table.Resources>

Problem

I'm trying to get a style to apply another style to elements of a certain type. Similar to CSS where you would do ``` div a { background-color:red; } ``` To apply a red background to all <a> elements that are contained by <div> elements. Specifically, I'm trying to get all TableCells contained within a TableRowGroup with a certain style to have their borders changed. I have the following solution where each cell style is set individually. ``` <Table> <Table.Columns> <TableColumn/> <TableColumn/> </Table.Columns> <Table.Resources> <Style x:Key="HeaderStyle" TargetType="{x:Type TableRowGroup}"> <Setter Property="FontWeight" Value="Normal"/> <Setter Property="FontSize" Value="12"/> </Style> <Style x:Key="HeaderCellStyle" TargetType="{x:Type TableCell}"> <Setter Property="BorderThickness" Value="0,1,0,1" /> <Setter Property="BorderBrush" Value="Black" /> </Style> </Table.Resources> <TableRowGroup Name="TableColumnHeaders" Style="{StaticResource HeaderStyle}"> <TableRow> <TableCell Style="{StaticResource HeaderCellStyle}"> <Paragraph> Description </Paragraph> </TableCell> <TableCell Style="{StaticResource HeaderCellStyle}"> <Paragraph> Amount </Paragraph> </TableCell> </TableRow> </TableRowGroup> </Table> ``` This is clearly not preferred as it bloats the xaml when there are many cells. I've tried the following with no success. ``` <Table.Resources> <Style x:Key="HeaderStyle" TargetType="{x:Type TableRowGroup}"> <Style.Resources> <Style TargetType="{x:Type TableCell}"> <Setter Property="BorderThickness" Value="0,1,0,1" /> <Setter Property="BorderBrush" Value="Black" /> </Style> </Style.Resources> <Setter Property="FontWeight" Value="Normal"/> <Setter Property="FontSize" Value="12"/> </Style> </Table.Resources> ``` This also doesn't work for some reason, though is valid ``` <Table.Resources> <Style x:Key="HeaderStyle" TargetType="{x:Type TableRowGroup}"> <Setter Property="FontWeight" Value="Normal"/> <Setter Property="FontSize" Value="12"/> <Setter Property="TableCell.BorderThickness" Value="0,1,0,1" /> <Setter Property="TableCell.BorderBrush" Value="Black" /> </Style> </Table.Resources> ``` There's going to be a few row groups each with their own cell style and each containing many cells. Please tell me there's a better way.

Original source