【问题标题】:How do I set the URI to an object in a ResourceDictionary from another assembly?如何将 URI 设置为来自另一个程序集的 ResourceDictionary 中的对象?
【发布时间】:2015-03-16 10:46:00
【问题描述】:

什么有效

我正在使用一个名为“WPF 动画 GIF”的插件,它允许我将动画 gif 设置为图像的图像源。我的问题是我正在使用来自另一个项目的图像。这些图像是 ResourceDictionary 中的键,如下所示:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    ...
    <ImageSource x:Key="ImgSyncFailed">Images/Sync Failed.png</ImageSource>
    <ImageSource x:Key="ImgSyncSucceeded">Images/Sync Succeeded.png</ImageSource>
    <ImageSource x:Key="ImgSyncing">Images/Syncing-Small.gif</ImageSource>
</ResourceDictionary>

资源字典通过引用和XAML添加到另一个项目中:

<Window.Resources>
    <ResourceDictionary Source="pack://application:,,,/ResourcesDictionary;component/Dictionary.xaml"/>
</Window.Resources>

当您想通过 XAML 添加图像时,这很好用:

<Button x:Name="SyncButton" Focusable="False" Background="{x:Null}" BorderBrush="{x:Null}" Foreground="{x:Null}" Height="100" Width="100" Click="SyncButton_OnClick">
    <Image x:Name="SyncImage" gif:ImageBehavior.AnimatedSource="{StaticResource ImgSyncSucceeded}" HorizontalAlignment="Center" VerticalAlignment="Center" Width="100" Height="100"/>
</Button>

什么不起作用

当我切换按钮的图像时,我是通过代码来实现的:

    private void ChangeSyncImage()
    {
        switch (syncStatus)
        {
            case SyncStatus.Synced:
                ...
            case SyncStatus.Desynced:
                ...
            case SyncStatus.Syncing:
                var img3 = new BitmapImage();
                img3.BeginInit();
                img3.UriSource = new Uri("pack://application:,,,/SmartFridgeApplication;component/Images/Syncing-Small.gif");
                img3.EndInit();
                ImageBehavior.SetAnimatedSource(SyncImage, img3);
                break;
        }
    }

我不喜欢这样设置,它现在不起作用,因为该路径设置为同一个项目中的“图像”。

那么如何设置它以使用 XAML 代码中的 StaticResources?

【问题讨论】:

标签: c# wpf xaml resources


【解决方案1】:

资源字典使用查找树,所以首先它会查找控件资源,然后它会查找可视化树,直到找到资源,所以只要您在可视化树中的条目高于默认值值然后你的值将覆盖

但是,当您使用后面的代码绕过静态资源时,如果您使用 TryFindResource(ResourceKey),您将中断连接,您将保持资源字典查找不变

所以

ImageBehavior.SetAnimatedSource(SyncImage, TryFindResource("ImgSyncSucceeded"));

静态资源也应该是静态的,即不会改变,因此使用动态资源可能有助于 https://msdn.microsoft.com/en-us/library/ms748942%28v=vs.110%29.aspx

【讨论】:

  • 您可能需要将 TryFindResource 的返回值强制转换为 ImageSource。
  • 太棒了。这使我的开关盒更短。我讨厌那些乌里的!欣赏!
【解决方案2】:

使用值转换器您可以做到这一点(请注意,这是未经测试的代码,仅作为一般原则的示例提供)

public class SyncConverter : IValueConverter
{
    public object Synced {get;set;}
    public object Desynced{get;set;}
    public object Syncing{get;set;}
    public object Convert(object value, Type targetType, 
        object parameter, CultureInfo culture)
    {
        switch (value)
        {
            case SyncStatus.Synced:
                return Synced;
            case SyncStatus.Desynced:
                return Desynced;
            case SyncStatus.Syncing:
                return Syncing;
        }
    }

    public object ConvertBack(object value, Type targetType, 
        object parameter, CultureInfo culture)
    {
        return null;
    }
}

在 XAML 中使用以下内容

<Window.Resources>
    <l:SyncConverter x:Key="converter" Synced="{StaticResource ImgSyncSucceeded}" Desynced="{StaticResource ImgSyncFailed}" Syncing="{StaticResource ImgSyncing}"/>
</Window.Resources>

<Button x:Name="SyncButton" Focusable="False" Background="{x:Null}" BorderBrush="{x:Null}" Foreground="{x:Null}" Height="100" Width="100" Click="SyncButton_OnClick">
    <Image x:Name="SyncImage" gif:ImageBehavior.AnimatedSource="{Binding syncStatus, Converter={Static converter}}" HorizontalAlignment="Center" VerticalAlignment="Center" Width="100" Height="100"/>
</Button>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-21
    • 2012-08-17
    • 2020-12-07
    • 2022-12-10
    • 1970-01-01
    • 2020-07-29
    相关资源
    最近更新 更多