开发者

How to inherit XAML style and override property of child element?

we just got started with XAML and are still fighting with basic issues: Comi开发者_如何学JAVAng from CSS we'd like to define a generic button style with custom control template and then have a second style inherit everything from the first style using "basedon. This second style should then override properties such e.g. "foreground color" (which works) but also properties of child elements within our custom template such as the "background color" of e.g. an included border element etc. (which doesn't work).

What's the general approach to go about things like this? How far can we go with cascading styles?

Cheers!


You can use an inherited style with no key reference:

<Grid>
    <Grid.Resources>
        <!-- Definition of default appearance of a button -->
        <Style TargetType="Button" x:Key="Default">
            <Setter Property="Background" Value="Red"></Setter>
            <Setter Property="FontFamily" Value="Segoe Black" />
            <Setter Property="HorizontalAlignment" Value="Center" />
            <Setter Property="FontSize" Value="32pt" />
            <Setter Property="Foreground" Value="#777777" />
        </Style>
        <!-- Define general style that based is base on the default style of the button without a key reference-->
        <Style TargetType="Button" BasedOn="{StaticResource Default}"/>

        <!-- In sub style override the properties you need -->
        <Style BasedOn="{StaticResource Default}" TargetType="Button" x:Key="SubButton" >
            <Setter Property="FontSize" Value="8pt" />
        </Style>

    </Grid.Resources>

    <Button Content="Main" Height="51" HorizontalAlignment="Left" Margin="154,72,0,0" Name="button1" VerticalAlignment="Top" Width="141" />
    <Button Content="Sub" Style="{StaticResource SubButton}" Height="51" HorizontalAlignment="Left" Margin="154,162,0,0" Name="button2" VerticalAlignment="Top" Width="141" />
</Grid>


I have (In my WPF application) default (base) styles defined in ResourceDictionary in App.xaml (in startup project). For example for button as follows.

    <Style TargetType="Button">
        <Setter Property="Margin" Value="5"/>
        <Setter Property="FontWeight" Value="DemiBold"/>
        <Setter Property="FontSize" Value="16"/>
    </Style>

In all views I use (by default) this general style (automatically inherited)! When I need to change or add some property in default style (defined in App.xaml) I create new style based on default style.

    <Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
        <!-- change -->
        <Setter Property="Margin" Value="10" />
        <!-- add -->
        <Setter Property="Foreground" Value="Red" />
    </Style>

When I need hide or strongly redefined default style (in some view) I create new style (based on nothing).

    <Style TargetType="Button"/>

You can, of course, continues in inheritance in App.xaml or in specific view. You can based new named style on default style and use new style by name. For example RedButton and GreenButton style.

    <Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}" x:Key="RedButton">
        <Setter Property="Foreground" Value="Red" />
    </Style>

    <Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}" x:Key="GreenButton">
        <Setter Property="Foreground" Value="Green" />
    </Style>

Etc...

NOTE: instead define your style in App.xaml you can use standalone library (dll) with styles only and ResourceDictionary from your library to App.xaml ResourceDictionary.MergedDictionaries.


The standard approach to making a customizable control template is to use TemplateBinding in the template to bind to properties of the control, and then to set those properties in the child styles.

For example, this creates a button template with a Border control, and binds the Background of the Border to the Background property of the Button. By setting the Background property of the Button in other styles, it changes the Background property of the Border.

<StackPanel>
    <StackPanel.Resources>
        <Style x:Key="BaseButtonStyle" TargetType="Button">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Border
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            Background="{TemplateBinding Background}">
                            <ContentPresenter/>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <Style x:Key="BlueButtonStyle" TargetType="Button"
               BasedOn="{StaticResource BaseButtonStyle}">
            <Setter Property="Background" Value="Blue"/>
        </Style>
        <Style x:Key="RedButtonStyle" TargetType="Button"
               BasedOn="{StaticResource BaseButtonStyle}">
            <Setter Property="Background" Value="Red"/>
        </Style>
    </StackPanel.Resources>
    <Button Style="{StaticResource RedButtonStyle}">Red</Button>
    <Button Style="{StaticResource BlueButtonStyle}">Blue</Button>
</StackPanel>

Many of the properties on Control are intended to be used in control templates, and won't affect other behavior if they are changed. They are BorderBrush, BorderThickness, Background, Padding, HorizontalContentAlignment, and VerticalContentAlignment.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜