简体   繁体   中英

Proper way to override style values in WPF

I want to edit a the cell style of a DataGrid in WPF. So using Expression Blend I right go to - Objects and Timeline>>DataGrid>>Edit Additional Templates>>Edit CellStyle>>Edit a Copy
Here's what what appears on the page:

<SolidColorBrush x:Key="{x:Static DataGrid.FocusBorderBrushKey}" Color="#FF000000"/>
<Style x:Key="DataGridCellStyle1" TargetType="{x:Type DataGridCell}">
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="BorderBrush" Value="Transparent"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type DataGridCell}">
                <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                    <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsSelected" Value="True">
            <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
            <Setter Property="BorderBrush" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
        </Trigger>
        <Trigger Property="IsKeyboardFocusWithin" Value="True">
            <Setter Property="BorderBrush" Value="{DynamicResource {x:Static DataGrid.FocusBorderBrushKey}}"/>
        </Trigger>
    </Style.Triggers>
</Style>

But I only want to change the padding and background. Instead it has given me 25 lines of code, including the cell template! Am I missing something, is there a better way of styling items like this without having to bring so much extra unnecessary code when I only want to change two items?

Check out the " BasedOn " attribute for Styles...

For example the following style takes everything from DataGridColumnHeader and only overrides the HorizontalContentAlignment property:

<Style x:Key="CenterAlignedColumnHeaderStyle" TargetType="{x:Type DataGridColumnHeader}" 
       BasedOn="{StaticResource {x:Type DataGridColumnHeader}}">
    <Setter Property="HorizontalContentAlignment" Value="Center"/>
</Style>

Overriding control templates in WPF requires you to completely replace the template. You may have wanted to change just the one aspect of the template but the result of that is Expression dumping a copy of the rest of the template so that it can be overridden. Make sure you're overriding the cell in the proper way (I'm not sure there's another way). Some controls ( ListView comes to mind) will let you swap out data templates without overriding the entire control template, but I'm not sure that's what you want, or if it can be done with DataGrid .

See the answer to this: Replace part of default template in WPF

To do what you want to do, you would usually just set the background and Padding properties in a style:

<Style TargetType="DataGridCell">
    <Setter Property="Padding" Value="10" />
    <Setter Property="Background" Value="Green" />
</Style>

However in this case it seems that the default control template for DataGridCell ignores the padding value, so you will need to replace it with an implementation that doesn't. The following is based on the default template that you posted:

<Style TargetType="DataGridCell">
    <Setter Property="Padding" Value="10" />
    <Setter Property="Background" Value="Green" />
    <Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="{x:Type DataGridCell}">
            <Border BorderBrush="{TemplateBinding BorderBrush}" 
                    BorderThickness="{TemplateBinding BorderThickness}" 
                    Background="{TemplateBinding Background}" 
                    SnapsToDevicePixels="True">
                <ContentPresenter 
                    Margin="{TemplateBinding Padding}" <!-- this bit does the padding -->
                    SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
            </Border>
        </ControlTemplate>
    </Setter.Value>
    </Setter>
</Style>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM