是否可以创建默认使用的隐式样式作为其他样式的基础?

时间:2014-07-23 16:52:57

标签: silverlight xaml controltemplate

我试图想出一种为自定义控件创建隐式样式的方法,该方法将由应用于控件的其他样式继承。

例如,我们说我有一个控件FancyButton。然后我可以通过将它放在我的应用程序资源中来定义隐式样式:

<Style TargetType="my:FancyButton">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="my:FancyButton">
                <TextBlock Text="hello world" Foreground="{TemplateBinding Foreground}" />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

然后控件的用户将看到&#34; hello world&#34;以绿色写作:

<my:FancyButton Foreground="Green" />

问题是,如果有人想要定义这样的绿色风格......

<Style TargetType="my:FancyButton" x:Key="GreenButton">
    <Setter Property="Foreground" Value="Green" />
</Style>

<my:FancyButton Style="{StaticResource GreenButton}" />

...然后他们将失去隐式风格的控制模板,并且不会看到&#34; hello world&#34;。

当然,您可以定义基本样式,隐式样式继承...

<Style TargetType="my:FancyButton" x:Key="FancyButtonDefaultStyle">
    <!-- ... -->
</Style>

<Style TargetType="my:FancyButton" BasedOn="{StaticResource FancyButtonDefaultStyle}">
</Style>

...这样控件的用户可以继承默认样式:

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

但强制​​控件的用户记住基于密钥继承默认样式似乎很尴尬。是不是有某种方法可以使自定义控件的样式继承隐式样式,就像框架控件一样?

也就是说,我希望我的FancyButton的行为方式与Button相同,我可以定义一种不会消除其他默认样式属性的样式(尤其是ControlTemplate):

<Style TargetType="Button" x:Key="GreenButton">
    <Setter Property="Foreground" Value="Green" />
</Style>

2 个答案:

答案 0 :(得分:2)

您需要设置隐式样式定义

<Style TargetType="my:FancyButton">
    <!-- etc -->
</Style>

在特殊的“Themes / Generic.xaml”资源字典中(与定义控件类的程序集相同)。这使得所有样式都可以根据需要继承隐式样式。

很抱歉引用。 :)

希望这有帮助。

这是我的代码: MainPage.xaml中:

<UserControl x:Class="SilverlightApplication4.MainPage"
             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"
             xmlns:local="clr-namespace:SilverlightApplication4"
             mc:Ignorable="d"
             d:DesignHeight="300"
             d:DesignWidth="400">

    <UserControl.Resources>
        <ResourceDictionary>                

            <Style TargetType="local:TemplatedControl1"
                   x:Key="myCustomTemplate">

                <Setter Property="Foreground"
                        Value="Purple" />
            </Style>

        </ResourceDictionary>
    </UserControl.Resources>

    <Grid x:Name="LayoutRoot"
          Background="Yellow"
          Width="500"
          Height="500">

        <local:TemplatedControl1 Style="{StaticResource myCustomTemplate}" />             

    </Grid>
</UserControl>

现在在TemplatedControl.cs中不要忘记这个:

this.DefaultStyleKey = typeof(TemplatedControl1);

最后将你的隐式样式定义放在Themes \ Generic.xaml:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:SilverlightApplication4">

    <Style TargetType="local:TemplatedControl1">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:TemplatedControl1">
                    <TextBlock Text="hello world"
                               Foreground="{TemplateBinding Foreground}" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

使用此方法,结果应该是可怕的黄色背景中的紫色文本。 :)

答案 1 :(得分:2)

感谢@ Tanis83指出(非常简单)的答案。我只需要隐含的风格......

<Style TargetType="my:FancyButton">
    <!-- etc -->
</Style>

在特别&#34; Themes / Generic.xaml&#34;资源字典(与定义控件类的组件相同)。这使得所有样式都继承了隐式样式,正如我想的那样。