如何将 URI 设置为来自另一个程序集的 ResourceDictionary 中的对象?
How do I set the URI to an object in a ResourceDictionary from another assembly?
什么有效
我正在使用一个名为 "WPF Animated 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;
}
}
我不喜欢这样设置,现在也不起作用,因为该路径设置为 'Images',它在同一个项目中。
那么如何设置它以像在 XAML 代码中那样使用 StaticResources?
资源字典使用查找树,所以首先它会查找控件资源,然后它会查找可视化树直到找到资源,所以只要您在可视化树中的条目高于默认值然后您的值将覆盖
然而,当您使用隐藏代码绕过静态资源时,如果您使用 TryFindResource(ResourceKey)
,您将断开连接,您将保持资源字典查找完整无缺
所以
ImageBehavior.SetAnimatedSource(SyncImage, TryFindResource("ImgSyncSucceeded"));
静态资源也应该是静态的,即不会改变,因此使用动态资源可能有助于
https://msdn.microsoft.com/en-us/library/ms748942%28v=vs.110%29.aspx
使用值转换器可以做到这一点(请注意,这是未经测试的代码,仅作为一般原则的示例提供)
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>
什么有效
我正在使用一个名为 "WPF Animated 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;
}
}
我不喜欢这样设置,现在也不起作用,因为该路径设置为 'Images',它在同一个项目中。
那么如何设置它以像在 XAML 代码中那样使用 StaticResources?
资源字典使用查找树,所以首先它会查找控件资源,然后它会查找可视化树直到找到资源,所以只要您在可视化树中的条目高于默认值然后您的值将覆盖
然而,当您使用隐藏代码绕过静态资源时,如果您使用 TryFindResource(ResourceKey)
,您将断开连接,您将保持资源字典查找完整无缺
所以
ImageBehavior.SetAnimatedSource(SyncImage, TryFindResource("ImgSyncSucceeded"));
静态资源也应该是静态的,即不会改变,因此使用动态资源可能有助于 https://msdn.microsoft.com/en-us/library/ms748942%28v=vs.110%29.aspx
使用值转换器可以做到这一点(请注意,这是未经测试的代码,仅作为一般原则的示例提供)
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>