Xaml样式继承不按预期工作

时间:2017-01-17 16:39:48

标签: wpf xaml resourcedictionary

我在尝试使用Xaml样式的BasedOn属性时遇到问题。我创建了一个相当简单的风格作为例子。

该项目包含两个主要文件。 MainWindow.xaml和SquareButtonStyle.xaml。 SquareButtonStyle利用FontAwesome.WPF项目快速获取一些图像。

MainWindow基本上是一系列按钮,里面有一个图像和一些文本。

此示例的目标是具有三种不同的按钮大小。 A"媒体"尺寸和两种变体,"小"和#34;大",基于中等大小。

使用大型变体最容易看到问题。中等样式的中心TextAlignment,Margin和Red文本颜色设置(大型基于该样式)将丢失。似乎不是继承样式而只覆盖特定属性,而是继承默认样式并覆盖属性。

我做错了什么?似乎解决这个问题的唯一方法是不打扰使用BasedOn,只需创建三个单独的样式,并设置完整的属性列表。有办法解决这个问题吗?

SquareButtonStyle.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style TargetType="Button" x:Key="SquareButtonMediumStyle">
        <Setter Property="Margin" Value="5" />
        <Setter Property="Width" Value="80" />
        <Setter Property="Height" Value="80" />
        <Style.Resources>
            <Style TargetType="StackPanel">
                <Setter Property="Orientation" Value="Vertical" />
                <Style.Resources>
                    <Style TargetType="TextBlock">
                        <Setter Property="FontSize" Value="12" />
                        <Setter Property="TextAlignment" Value="Center" />
                        <Setter Property="Foreground" Value="Red"></Setter>
                        <Setter Property="TextWrapping" Value="Wrap" />
                    </Style>
                </Style.Resources>
            </Style>
        </Style.Resources>
    </Style>
    <Style BasedOn="{StaticResource SquareButtonMediumStyle}" TargetType="Button" x:Key="SquareButtonSmallStyle">
        <Setter Property="Width" Value="55" />
        <Setter Property="Height" Value="55" />
        <Style.Resources>
            <Style TargetType="StackPanel">
                <Style.Resources>
                    <Style TargetType="TextBlock">
                        <Setter Property="FontSize" Value="10" />
                    </Style>
                </Style.Resources>
            </Style>
        </Style.Resources>
    </Style>
    <Style BasedOn="{StaticResource SquareButtonMediumStyle}" TargetType="Button" x:Key="SquareButtonLargeStyle">
        <Setter Property="Width" Value="100" />
        <Setter Property="Height" Value="100" />
        <Style.Resources>
            <Style TargetType="StackPanel">
                <Style.Resources>
                    <Style TargetType="TextBlock">
                        <Setter Property="FontSize" Value="14" />
                    </Style>
                </Style.Resources>
            </Style>
        </Style.Resources>
    </Style>
</ResourceDictionary>   

MainWindow.xaml

<Window x:Class="XamlStyleExample.MainWindow"
                            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                            mc:Ignorable="d"
                            Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="SquareButtonStyle.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
    <StackPanel>
        <WrapPanel>
            <WrapPanel.Resources>
                <Style BasedOn="{StaticResource SquareButtonMediumStyle}" TargetType="Button" />
            </WrapPanel.Resources>
            <Button>
                <StackPanel>
                    <TextBlock>Button 1</TextBlock>
                </StackPanel>
            </Button>
            <Button>
                <StackPanel>
                    <TextBlock>Button 2</TextBlock>
                </StackPanel>
            </Button>
            <Button>
                <StackPanel>
                    <TextBlock>Button 3</TextBlock>
                </StackPanel>
            </Button>
        </WrapPanel>
        <WrapPanel>
            <WrapPanel.Resources>
                <Style BasedOn="{StaticResource SquareButtonSmallStyle}" TargetType="Button" />
            </WrapPanel.Resources>
            <Button>
                <StackPanel>
                    <TextBlock>Button 1</TextBlock>
                </StackPanel>
            </Button>
            <Button>
                <StackPanel>
                    <TextBlock>Button 2</TextBlock>
                </StackPanel>
            </Button>
            <Button>
                <StackPanel>
                    <TextBlock>Button 3</TextBlock>
                </StackPanel>
            </Button>
        </WrapPanel>
        <WrapPanel>
            <WrapPanel.Resources>
                <Style BasedOn="{StaticResource SquareButtonLargeStyle}" TargetType="Button" />
            </WrapPanel.Resources>
            <Button>
                <StackPanel>
                    <TextBlock>Button 1</TextBlock>
                </StackPanel>
            </Button>
            <Button>
                <StackPanel>
                    <TextBlock>Button 2</TextBlock>
                </StackPanel>
            </Button>
            <Button>
                <StackPanel>
                    <TextBlock>Button 3</TextBlock>
                </StackPanel>
            </Button>
        </WrapPanel>
    </StackPanel>
</Window>

更新

根据几个答案,我想出了一个解决方案,但我并不是特别喜欢它。看起来很乱。

我现在有两个键控样式。一个用于StackPanel,一个用于TextBlock。

MainWindow.Xaml保持不变,但SquaredButtonStyle.xaml现在有:

    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style TargetType="TextBlock" x:Key="SpecialTextBlockStyle">
        <Setter Property="TextAlignment" Value="Center" />
        <Setter Property="Foreground" Value="Red" />
        <Setter Property="TextWrapping" Value="Wrap" />
    </Style>

    <Style TargetType="StackPanel" x:Key="MediumNestedStackPanel">
        <Style.Resources>
            <Style TargetType="TextBlock" BasedOn="{StaticResource SpecialTextBlockStyle}" />
        </Style.Resources>
    </Style>

    <Style TargetType="Button" x:Key="SquareButtonMediumStyle">
        <Setter Property="Margin" Value="5" />
        <Setter Property="Width" Value="80" />
        <Setter Property="Height" Value="80" />
        <Style.Resources>
            <Style TargetType="StackPanel" BasedOn="{StaticResource MediumNestedStackPanel}">
            </Style>
        </Style.Resources>
    </Style>

    <Style BasedOn="{StaticResource SquareButtonMediumStyle}" TargetType="Button" x:Key="SquareButtonSmallStyle">
        <Setter Property="Width" Value="55" />
        <Setter Property="Height" Value="55" />
        <Style.Resources>
            <!-- 
            Implicit stack panel style in the scope of SquareButtonMediumStyle 
            inherits from MediumNestedStackPanel, adds stuff
            -->
            <Style TargetType="StackPanel" BasedOn="{StaticResource MediumNestedStackPanel}">
                <Style.Resources>
                    <Style TargetType="TextBlock" BasedOn="{StaticResource SpecialTextBlockStyle}" >
                        <Setter Property="FontSize" Value="10" />
                    </Style>
                </Style.Resources>
            </Style>
        </Style.Resources>
    </Style>

    <Style BasedOn="{StaticResource SquareButtonMediumStyle}" TargetType="Button" x:Key="SquareButtonLargeStyle">
        <Setter Property="Width" Value="100" />
        <Setter Property="Height" Value="100" />
        <Style.Resources>
            <Style TargetType="StackPanel" BasedOn="{StaticResource MediumNestedStackPanel}">
                <Style.Resources>
                    <Style TargetType="TextBlock" BasedOn="{StaticResource SpecialTextBlockStyle}">
                        <Setter Property="FontSize" Value="14" />
                    </Style>
                </Style.Resources>
            </Style>
        </Style.Resources>
    </Style>
</ResourceDictionary>

2 个答案:

答案 0 :(得分:1)

您应该设置Button元素本身的FontSize,Foreground,...属性,而不是在Button样式中定义隐式TextBlock样式:

<Style TargetType="Button" x:Key="SquareButtonMediumStyle">
    <Setter Property="Margin" Value="5" />
    <Setter Property="Width" Value="80" />
    <Setter Property="Height" Value="80" />
    <Setter Property="FontSize" Value="12" />
    <Setter Property="TextBlock.TextAlignment" Value="Center" />
    <Setter Property="Foreground" Value="Red"></Setter>
    <Setter Property="TextBlock.TextWrapping" Value="Wrap" />
    <Style.Resources>
        <Style TargetType="StackPanel">
            <Setter Property="Orientation" Value="Vertical" />
        </Style>
    </Style.Resources>
</Style>

<Style BasedOn="{StaticResource SquareButtonMediumStyle}" TargetType="Button" x:Key="SquareButtonLargeStyle">
    <Setter Property="Width" Value="100" />
    <Setter Property="Height" Value="100" />
    <Setter Property="FontSize" Value="14" />
</Style>

您目前使用TextBlocks的隐式样式的方法不会像您已经发现的那样工作。有关原因的详细信息,请参阅以下链接:

Wpf, style is not being applied

答案 1 :(得分:1)

这些嵌套的StackPanel样式不会涉及其包含样式的BasedOn继承。如果要这样做,则必须为嵌套样式设置单独的继承层次结构:

<Style TargetType="StackPanel" x:Key="MediumNestedStackPanel">
    <Setter Property="Orientation" Value="Vertical" />
    <Style.Resources>
        <Style TargetType="fa:ImageAwesome">
            <Setter Property="Height" Value="35" />
            <Setter Property="Margin" Value="5" />
        </Style>
        <Style TargetType="TextBlock">
            <Setter Property="FontSize" Value="12" />
            <Setter Property="TextAlignment" Value="Center" />
            <Setter Property="Foreground" Value="Red"></Setter>
            <Setter Property="TextWrapping" Value="Wrap" />
        </Style>
    </Style.Resources>
</Style>

<Style TargetType="Button" x:Key="SquareButtonMediumStyle">
    <Setter Property="Margin" Value="5" />
    <Setter Property="Width" Value="80" />
    <Setter Property="Height" Value="80" />
    <Style.Resources>
        <!-- 
        Implicit stack panel style in the scope of SquareButtonMediumStyle 
        inherits from MediumNestedStackPanel, adds nothing
        -->
        <Style 
            TargetType="StackPanel" BasedOn="{StaticResource MediumNestedStackPanel}"
            />
    </Style.Resources>
</Style>

<Style BasedOn="{StaticResource SquareButtonMediumStyle}" TargetType="Button" x:Key="SquareButtonSmallStyle">
    <Setter Property="Width" Value="55" />
    <Setter Property="Height" Value="55" />
    <Style.Resources>
        <!-- 
    Implicit stack panel style in the scope of SquareButtonMediumStyle 
    inherits from MediumNestedStackPanel, adds stuff
    -->
        <Style TargetType="StackPanel" BasedOn="{StaticResource MediumNestedStackPanel}">
            <Style.Resources>
                <Style TargetType="fa:ImageAwesome" BasedOn="{StaticResource {x:Type fa:ImageAwesome}}">
                    <Setter Property="Height" Value="20" />
                </Style>
                <Style TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}">
                    <Setter Property="FontSize" Value="10" />
                </Style>
            </Style.Resources>
        </Style>
    </Style.Resources>
</Style>

<Style BasedOn="{StaticResource SquareButtonMediumStyle}" TargetType="Button" x:Key="SquareButtonLargeStyle">
    <Setter Property="Width" Value="100" />
    <Setter Property="Height" Value="100" />
    <Style.Resources>
        <Style TargetType="StackPanel" BasedOn="{StaticResource MediumNestedStackPanel}">
            <Style.Resources>
                <Style TargetType="fa:ImageAwesome" BasedOn="{StaticResource {x:Type fa:ImageAwesome}}">
                    <Setter Property="Height" Value="60" />
                    <Setter Property="Margin" Value="5" />
                </Style>
                <Style TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}">
                    <Setter Property="FontSize" Value="14" />
                </Style>
            </Style.Resources>
        </Style>
    </Style.Resources>
</Style>