我有一个应用程序,其中定义了多个ThemeResources来为要使用的多个图像设置正确的Source。我有大约12张图片,可以让我的应用根据需要自动设置亮或暗主题。

<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'的属性,其中包含必须显示的Image的ThemeResource的名称。

我想使用ViewModel中的属性执行对Image控件的ThemeResource分配。因此,例如以下..在这种情况下,属性ImageToshow将包含字符串值ShowImage
<Grid>
    <Image HorizontalAlignment="Center"
       VerticalAlignment="Center"
       Stretch="None"
       Style="{ThemeResource ImageToShow}">
    </Image>
</Grid>

但是,这给了我一个XamlParseException。

是否可以通过从MVVM进行绑定(bind)来设置ThemeResource?还是应该使用某种转换器来确保使用字符串的值来选择ThemeResource。

最佳答案

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

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

因此,您应该能够从 View 模型属性的 setter 中返回该值,如下所示:
public Image ImageToShow
{
    get { return (Image)Application.Current.Resources["ShowImage"]; }
}

唯一的问题是,当属性值更改时,您将需要手动通知INotifyPropertyChanged接口(interface),以便将更改通知给UI:
NotifyPropertyChanged("ImageToShow");

您可以在MSCerts网站上的User Interface : Detecting Changes in the Theme Template页面上找到有关此操作的示例。

请参阅MSDN上的How to apply theme resources for Windows Phone页面以获取更多信息。

10-05 18:12