简体   繁体   English

通过从App.xaml绑定加载ResourceDictionary?

[英]Loading a ResourceDictionary via binding from App.xaml?

I have a WPF application that we need to reskin depending on a configuration file setting. 我有一个WPF应用程序,我们需要根据配置文件设置来重新设置外观。 The simple version of the App.xaml is: App.xaml的简单版本是:

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>

I want to load the resourcedictionary at runtime based on a config file setting. 我想在运行时基于配置文件设置加载resourcedictionary。 I've already hooked up the binding and know that it works, but I can't determine a way to merge this specific dictionary in. 我已经绑定了绑定,并且知道它可以工作,但是我无法确定一种方法来合并此特定词典。

MainWindowView.xaml 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>

Where the MainWindowViewModel is something simple like: MainWindowViewModel如下所示:

MainWindowViewModel.cs MainWindowViewModel.cs

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

Is there a way to do this properly? 有没有办法正确地做到这一点?

Edit: I don't want to do the loading in codebehind and PACK syntax does not seem like what the engine was built for in this case. 编辑:我不想在代码隐藏中进行加载,在这种情况下,PACK语法看起来不像是为该引擎构建的。

Edit 2: I'm a bit close using this code in the App.xaml: 编辑2:我在App.xaml中使用以下代码有点接近:

    <StaticResource ResourceKey="{Binding Path=IsAlternate, Converter={StaticResource BoolToResourceKeyId}}" />

But it causes a bunch of weird errors to crop up in my view when I have that. 但是在我看来,这会引起很多奇怪的错误。

After a few more hours of fighting, I found a different way of handling the situation. 经过几个小时的战斗,我发现了处理情况的另一种方法。

I created two styles for the control I was working in app.xaml: 我为在app.xaml中使用的控件创建了两种样式:

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>
   ...

Then defined a converter that could be used to locate the styles: 然后定义一个可用于定位样式的转换器:

IsMainToStyleConverter.cs 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;
    }
}

And fixed up my MainWindowView: 并修复了我的MainWindowView:

MainWindowView.xaml MainWindowView.xaml

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

Now as long as my viewmodel has the right property, the converter handles locating the style resources and changing over to it without having to worry about transcending pattern concerns or anything like that. 现在,只要我的viewmodel具有正确的属性,转换器就可以定位样式资源并转换为样式资源,而不必担心会超越模式问题或类似问题。

I don't think there is a syntax to do this in XAML based on your binding. 我认为XAML中没有基于您的绑定的语法。

But what you can do, is create an event handler on your viewModel's PropertyChanged event, and in this handler, check the value of "IsAlternate" then use: 但是,您可以做的是在viewModel的PropertyChanged事件上创建一个事件处理程序,然后在此处理程序中检查“ IsAlternate”的值,然后使用:

Application.Current.Resources.MergedDictionaries.Add

and pack URIs, to add/remove the correct resource dictionnary 并打包URI,以添加/删除正确的资源字典

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM