如何继承XAML样式并覆盖子元素的属性?

时间:2010-09-07 08:00:17

标签: wpf xaml

我们刚刚开始使用XAML并且仍然在解决基本问题: 来自CSS我们想要定义一个带有自定义控件模板的通用按钮样式,然后让第二个样式继承使用“basedon”的第一个样式。第二个样式应该覆盖属性,例如“前景色”(有效)还有我们自定义模板中的子元素的属性,例如包含边框元素等的“背景颜色”(这不起作用)。

这样做的一般方法是什么?我们可以用级联风格走多远?

干杯!

3 个答案:

答案 0 :(得分:29)

您可以使用没有键引用的继承样式:

<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>

答案 1 :(得分:17)

我在(在我的WPF应用程序中)在App.xaml(在启动项目中)的ResourceDictionary中定义的默认(基本)样式。例如按钮如下。

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

在所有视图中,我使用(默认情况下)这种通用样式(自动继承)!当我需要更改或添加默认样式的某个属性(在App.xaml中定义)时,我会根据默认样式创建新样式。

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

当我需要隐藏或强烈重新定义默认样式时(在某些视图中)我创建新样式(基于什么都没有)。

    <Style TargetType="Button"/>

当然,您可以继续在App.xaml或特定视图中继承。您可以在默认样式上使用新的命名样式,并按名称使用新样式。例如RedButton和GreenButton样式。

    <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>

等等...

注意:而是在App.xaml中定义您的样式,您可以使用仅包含样式的独立库(dll)和从库到App.xaml ResourceDictionary.MergedDictionaries的ResourceDictionary。

答案 2 :(得分:8)

制作可自定义控件模板的标准方法是使用模板中的TemplateBinding绑定到控件的属性,然后在子样式中设置这些属性。

例如,这将创建一个带有边框控件的按钮模板,并将边框的背景绑定到Button的Background属性。通过在其他样式中设置Button的Background属性,它会更改Border的Background属性。

<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>

Control上的许多属性都旨在用于控件模板,如果更改,则不会影响其他行为。它们是BorderBrush,BorderThickness,Background,Padding,Horizo​​ntalContentAlignment和VerticalContentAlignment。