如何通过绑定MVVM为Image控件设置特定的ThemeResource?

How to set specific ThemeResource for Image control through binding with MVVM?

我有一个应用程序,我在其中定义了多个 ThemeResources 来为我想使用的多个图像设置正确的源。我有大约一打图像,我可以让应用程序根据需要自动设置浅色或深色主题。

<ResourceDictionary>
  <ResourceDictionary.ThemeDictionaries>
    <ResourceDictionary x:Key="Light">
        <Style x:Key="ShowImage" TargetType="Image">
            <Setter Property="Source" Value="Assets/image-light.png"/>                            
        </Style>
    </ResourceDictionary>
    <ResourceDictionary x:Key="Dark">
        <Style x:Key="ShowImage" TargetType="Image">
            <Setter Property="Source" value="Assets/image-dark.png"/>
        </Style>
    </ResourceDictionary>                
</ResourceDictionary.ThemeDictionaries>

现在,如果我想在 XAML 中设置特定的内联图像,我使用以下代码。

<Grid>        
    <Image HorizontalAlignment="Center" 
       VerticalAlignment="Center" 
       Stretch="None" 
       Style="{ThemeResource ShowImage}">
    </Image>
</Grid>

这对我的所有图像都非常有效,并且始终遵循正确的主题。

我正在尝试更改此代码。我必须显示的图像基于我在 MVVM ViewModel 中执行的一些逻辑和计算。

在我的 ViewModel 中,我有一个 属性 类型的字符串 'ImageToShow',其中包含必须显示的图像的 ThemeResource 名称。

我想使用 ViewModel 中的 属性 对 Image 控件执行 ThemeResource 分配。因此,例如以下 .. 在这种情况下,属性 ImageToshow 将包含字符串值 ShowImage.

<Grid>        
    <Image HorizontalAlignment="Center" 
       VerticalAlignment="Center" 
       Stretch="None" 
       Style="{ThemeResource ImageToShow}">
    </Image>
</Grid>

然而,这给了我一个 XamlParseException。

是否可以通过从 MVVM 绑定来设置 ThemeResource?或者我应该使用某种转换器来确保字符串的值用于 select ThemeResource。

我相信您应该能够使用 Application.Current.Resources 对象访问当前所选主题的相关资源...例如:

Image image = (Image)Application.Current.Resources["ShowImage"];

因此,您应该能够 return 来自视图模型 属性 的 setter 的值,如下所示:

public Image ImageToShow
{
    get { return (Image)Application.Current.Resources["ShowImage"]; }
}

唯一的问题是,当 属性 值发生变化时,您需要手动通知 INotifyPropertyChanged 接口,以便将变化通知给 UI :

NotifyPropertyChanged("ImageToShow");

您可以在 MSCerts 网站的 User Interface : Detecting Changes in the Theme Template 页面中找到如何执行此操作的示例。

有关详细信息,请参阅 MSDN 上的 How to apply theme resources for Windows Phone 页面。