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

Flo*_*sta 21 wpf xaml

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

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

干杯!

小智 32

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

<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>
Run Code Online (Sandbox Code Playgroud)


hon*_*989 18

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

    <Style TargetType="Button">
        <Setter Property="Margin" Value="5"/>
        <Setter Property="FontWeight" Value="DemiBold"/>
        <Setter Property="FontSize" Value="16"/>
    </Style>
Run Code Online (Sandbox Code Playgroud)

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

    <Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
        <!-- change -->
        <Setter Property="Margin" Value="10" />
        <!-- add -->
        <Setter Property="Foreground" Value="Red" />
    </Style>
Run Code Online (Sandbox Code Playgroud)

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

    <Style TargetType="Button"/>
Run Code Online (Sandbox Code Playgroud)

当然,您可以继续在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>
Run Code Online (Sandbox Code Playgroud)

等等...

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


Qua*_*ter 9

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

例如,这将创建一个带有Border控件的按钮模板,并将Border的Background背景绑定到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>
Run Code Online (Sandbox Code Playgroud)

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