将一个资源字典包含在另一个资源字典中



我正在为我的c#/XAML应用程序设计一些主题,并希望在一个XAML文件(ResourceDictionary)中定义我的主题,在其他几个XAML文件(ResourceDictionaries)中使用颜色变化。

所以,我在尝试:

<Style TargetType="ListBox">
<Setter Property="Foreground" Value="{StaticResource ResourceKey=ForegroundBrush}" />
<Setter Property="Background" Value="{StaticResource ResourceKey=BackgroundBrush}" />
</Style>

在一个通用的主题XAML文件是在一个类库,并不是从我的主应用程序引用。然后我有第二个文件:

<Color x:Key="BackgroundColour" A="#FF" R="#10" G="#10" B="#40" />
<Color x:Key="BackgroundColour2" A="#FF" R="#10" G="#10" B="#FF" />
<Color x:Key="BorderColour" A="#FF" R="#00" G="#00" B="#FF" />
<Color x:Key="ForegroundColour" A="#FF" R="#FF" G="#FF" B="#FF" />
<Color x:Key="ForegroundColour2" A="#FF" R="#80" G="#80" B="#FF" />
<LinearGradientBrush x:Key="GradientForegroundBrush" EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="{StaticResource ForegroundColour}" Offset="0"/>
<GradientStop Color="{StaticResource ForegroundColour2}" Offset="1"/>
</LinearGradientBrush>

我显然可以有几个这样的文件定义不同的颜色在相同的基本主题。我已经尝试过:

<ResourceDictionary Source="basestyle.xaml" x:Key="basestyle" />

我会参考bluestyle.xaml,redstyle.xaml等…来自我的申请。如果我将整个主题复制到每个文件中,这将工作得很好,但是能够重用基本代码似乎更整洁。

有办法做到这一点吗?

如果你想从主题样式和控件模板中分离画笔或特定样式等资源,你可以简单地创建通用的ThemesGeneric.xaml资源字典,引用资源键,就像你在示例中所做的那样,例如ForegroundBrush

然后你可以创建一个特定的样式资源字典,例如redstyle.xaml,它包含所有具有相应键的资源。或者,您可以另外创建另一个basestyle.xaml资源字典,其中包含您不想存储在主题资源字典中的所有具体主题变体共享的一些资源。

为了应用样式,将必要的资源字典作为合并字典添加到App.xaml文件中。请注意,顺序很重要。首先包含其他资源字典需要的资源字典。对StaticResources和DynamicResources的查找将找到具有匹配键的资源,这是最后添加的。有关这方面的更多信息,请参阅XAML资源引用的查找行为。

<Application x:Class="YourApplication"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>

<!-- Base style that includes all default resources and styles. -->
<ResourceDictionary Source="basestyle.xaml"/>

<!-- Red style that includes just specific resources and style that changed. -->
<ResourceDictionary Source="redstyle.xaml"/>

<!-- Your control theme that references the resources and styles. -->
<ResourceDictionary Source="Themes/Generic.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>

如果你想在运行时切换样式,你必须在代码中替换相应的字典,例如:

  • App.xaml.cs中通过修改Resources字典
  • 使用Application.Current.Resources.

如果不替换所有字典,包括您的通用控制主题字典,您将不得不使用DynamicResource标记扩展而不是StaticResource,因为后者不会在运行时获取引用资源的更改。

StaticResource Markup Extension通过在所有可用的资源字典中查找键的值来处理键。处理发生在加载期间,此时加载进程需要分配属性值。DynamicResource Markup Extension通过创建一个表达式来处理键,并且该表达式在应用运行之前保持不求值,此时该表达式被求值并提供一个值。

是您可以创建不同的资源。在同一个项目中,你只需要在App.cs代码中加载这些文件,

if(_theme=="theme1")//you can use switch statement if themes are more
{
ResourceDictionary myResourceDictionary1 = new ResourceDictionary();
myResourceDictionary1.Source = new Uri("theme1.xaml", UriKind.Relative);
Application.Current.Resources.MergedDictionaries.Add(myResourceDictionary1);
}
else
{
ResourceDictionary myResourceDictionary2 = new ResourceDictionary();
myResourceDictionary2.Source = new Uri("theme2.xaml", UriKind.Relative);
Application.Current.Resources.MergedDictionaries.Add(myResourceDictionary2);
}

最新更新