绑定到ResourceDictionary中的静态主题

时间:2015-05-19 19:21:40

标签: c# xaml silverlight windows-phone-8

我正在尝试为WP8应用创建自定义主题。不是内置的深色/浅色主题,而是自定义的白色标签主题。为了使它工作,我创建了一个静态类,如:

public class Theme : DependencyObject
{
    static Theme()
    {
        CurrentTheme = new DefaultAppTheme();
    }

    public static IAppTheme CurrentTheme { get; set; }
}

然后我可以通过首先在Resource部分中包含一个引用来绑定到页面中的static属性:

<pages:PhoneApplicationPage.Resources>
    <ResourceDictionary>
        <ui:Theme x:Key="Theme"/>
    </ResourceDictionary>
</pages:PhoneApplicationPage.Resources>

最后:

<Rectangle Fill="{Binding Path=CurrentTheme.DarkIconBrush, Source={StaticResource Theme}, Mode=OneTime}">

到目前为止一切顺利。唯一剩下的就是在/Themes/Generic.xaml文件中做同样的事情,但我不能为我的生活弄清楚如何。

我可以通过运行应用程序验证上面的绑定是否像魅力一样。通过在App ctor中设置Theme.CurrentTheme,我可以更改应用程序的主题。

如何将Generic.xaml绑定到Theme类的颜色属性?这就是我的尝试:

  1. 将资源部分添加到Generic.xaml中的ResourceDictionary - 不起作用,因为该类不支持

  2. 尝试将其声明为Generic.xaml中的变量(资源)并引用它,如:

    &lt; ui:主题x:关键=&#34; MyTheme&#34; /&gt;

  3. 不确定绑定语法在这里的样子。

    1. 做一些奇怪的附加属性绑定魔法来解决这个问题。
    2. Generic.xaml在App项目中,它位于用户控件项目(库)中。否则我可以将它添加到App类&#39;资源部分。

1 个答案:

答案 0 :(得分:0)

免责声明:我不是WP开发人员,我开发的是普通的桌面浏览器Silverlight。

我的心理模型默认样式模板 generic.xaml 主题如何协同工作是以下(这也可能对您有用):

为了使我的(模板化的)自定义控件在整个应用程序中正常工作,框架必须能够找到默认模板。因此,包含这些模板的默认样式包含在generic.xaml中。 心理模型:generic.xaml绝不涉及主题,它唯一关心的是为我的自定义类型提供模板(和默认设置),因此我的应用程序UI在技术上可用。

我的责任是我的默认模板实际绑定并使用与控件外观相关的公共依赖项属性:Background,BorderBrush,BorderThickness,Foreground,Padding

也许我必须自己添加一个或两个属性以允许自定义我的控件:

[StyleTypedProperty( Property = "ToggleButtonStyle", StyleTargetType = typeof( ToggleButton ) )]
[StyleTypedProperty( Property = "DropDownBackgroundStyle", StyleTargetType = typeof( Border ) )]
public class DropDownButton : Control
{
    ...

    public Style ToggleButtonStyle
    {
        get { return (Style) GetValue( ToggleButtonStyleProperty ); }
        set { SetValue( ToggleButtonStyleProperty, value ); }
    }

    public static readonly DependencyProperty ToggleButtonStyleProperty =
        DependencyProperty.Register( "ToggleButtonStyle", typeof( Style ), typeof( DropDownButton ), null );

    public Style DropDownBackgroundStyle
    {
        get { return (Style) GetValue( DropDownBackgroundStyleProperty ); }
        set { SetValue( DropDownBackgroundStyleProperty, value ); }
    }

    public static readonly DependencyProperty DropDownBackgroundStyleProperty =
        DependencyProperty.Register( "DropDownBackgroundStyle", typeof( Style ), typeof( DropDownButton ), null );

}

心理模型:我可以在自定义控件中构建自定义/可定性。

如果在一个具体的应用程序(和一个不同的程序集)中我需要我的控件来跟随一个主题(不需要为每一次出现都明确设置一个样式)我必须提供一个单独的默认样式,但是新的默认样式style仅设置与外观有关的属性: 所以我会在我的App.xaml中添加这样的东西:

<Application.Resources>
    <ResourceDictionary>
        <ui:Theme x:Key="Theme"/>
        <Style TargetType="ToggleButton" x:Key="ThemedToggleButtonStyle">
            <Setter Property="Background" Value="{Binding Path=CurrentTheme.DarkIconBrush, Source={StaticResource Theme}, Mode=OneTime}"/>
        </Style>
        <!-- implicity default style for all ToggleButtons -->
        <Style TargetType="ToggleButton" BasedOn="{StaticResource ThemedToggleButtonStyle}"/>
        <!-- implicity default style for all DropDownButtons -->
        <Style TargetType="controls:DropDownButton">
            <Setter Property="ToggleButtonStyle" Value="{StaticResource ThemedToggleButtonStyle}"/>
            <Setter Property="Background" Value="{Binding Path=CurrentTheme.DarkIconBrush, Source={StaticResource Theme}, Mode=OneTime}"/>
        </Style>
    </ResourceDictionary>
</Application.Resources>

心理模型:对于要在我的一个具体应用中应用的主题,我必须“添加第二层”隐式默认样式。我的具体应用程序关注的是提供该层,而不是我的自定义控件组合的关注。