通过App.xaml的绑定加载一个ResourceDictionary

本文关键字:一个 ResourceDictionary 加载 App xaml 绑定 通过 | 更新日期: 2023-09-27 18:11:09

我有一个WPF应用程序,我们需要根据配置文件设置重新皮肤。App.xaml的简单版本是:

App.xaml

<Application>
  ...
  <Application.Resources>
    <ResourceDictionary x:Key="NormalMain">
        <ImageBrush x:Key="BackgroundBrush" ImageSource="Images/welcome.png"/>
    </ResourceDictionary>
    <ResourceDictionary x:Key="AlternateMain">
        <SolidColorBrush x:Key="BackgroundBrush" Color="LightGreen"/>
    </ResourceDictionary>
  </Application.Resources>
  ...
</Application>

我想在运行时基于配置文件设置加载资源字典。我已经连接了绑定,并且知道它可以工作,但是我不能确定一种方法来合并这个特定的字典。

MainWindowView.xaml

<Window 
    (...)
    d:DataContext="{d:DesignInstance designer:DesignMainWindowViewModel, IsDesignTimeCreatable=True}"
    Background="{StaticResource BackgroundBrush}">
    ...
    <Window.Resources>
      //Load dictionary based on binding here?
    </Window.Resources>
</Window>

其中MainWindowViewModel是一些简单的东西,如:

MainWindowViewModel.cs

public class MainWindowViewModel {
  public bool IsAlternate {get;set;}
}

有办法正确地做到这一点吗?

编辑:我不想在代码隐藏和PACK语法中做加载,似乎不像引擎在这种情况下构建的。

编辑2:我有点接近使用这段代码在App.xaml:
    <StaticResource ResourceKey="{Binding Path=IsAlternate, Converter={StaticResource BoolToResourceKeyId}}" />

但是它会导致一些奇怪的错误出现在我的视图中当我有这个

通过App.xaml的绑定加载一个ResourceDictionary

经过几个小时的战斗,我找到了一个不同的方法来处理这种情况。

我为app.xaml中的控件创建了两种样式:

App.xaml

   ...
    <valueConverters:IsMainToStyleConverter x:Key="IsMainToStyleConverter" />
    <Style x:Key="Main" TargetType="Window">
        <Setter Property="Background" Value="{StaticResource MainBackgroundBrush}" />
    </Style>
    <Style x:Key="Alternate" TargetType="Window">
        <Setter Property="Background" Value="{StaticResource AlternateBackgroundBrush}" />
    </Style>
   ...

然后定义了一个可用于定位样式的转换器:

IsMainToStyleConverter.cs

public class IsMainToStyleConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return Application.Current.TryFindResource((value is bool && ((bool)value) ? "Main" : "Alternate"));
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return Binding.DoNothing;
    }
}

修复了我的MainWindowView:

MainWindowView.xaml

<Window 
   ...
   d:DataContext="{d:DesignInstance designer:DesignMainWindowViewModel, IsDesignTimeCreatable=True}"
   Style="{Binding IsMain, Converter={StaticResource IsMainConverter}}">
   ...
</Window>

现在,只要我的视图模型具有正确的属性,转换器就可以处理样式资源的定位并将其转换为样式资源,而不必担心超越模式关注点或类似的事情。

我认为在XAML中没有基于绑定的语法。

但是你能做的,是在你的viewModel的PropertyChanged事件上创建一个事件处理程序,在这个处理程序中,检查"IsAlternate"的值,然后使用:

Application.Current.Resources.MergedDictionaries.Add

和打包uri,以添加/删除正确的资源字典

相关文章: