Including Optional Resource in WPF Window

I want to be able to use either a default bitmap resource or one provided by a separate assembly in a WPF window.I thought I could do this by defining the default bitmap in the Window.Resources section, and then search for and load if found the resources from the separate optional assembly:

[xaml file for window]

<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary>
                <BitmapImage x:Key="J4JWizardImage" UriSource="../assets/install.png"/>
            </ResourceDictionary>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Window.Resources>

[code behind for window constructor]

try
{
    var resDllPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Olbert.JumpForJoy.DefaultResources.dll");

    if( File.Exists( resDllPath ) )
    {
        var resAssembly = Assembly.LoadFile( resDllPath );
        var uriText =
                    $"pack://application:,,,/{resAssembly.GetName().Name};component/DefaultResources.xaml";

        ResourceDictionary j4jRD =
            new ResourceDictionary
            {
                Source = new Uri( uriText )
            };

        Resources.Add( J4JWizardImageKey, j4jRD[ "J4JWizardImage" ] );
    }
}
catch (Exception ex)
{
}

InitializeComponent();

However, the default image was always displayed, even when the separate resource assembly was present. Apparently, resources defined within a Window definition take precedence over resources added when the window is constructed.

So I removed the Window.Resources section, added a standalone resource xaml file:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:Olbert.Wix.views">
    <BitmapImage x:Key="DefaultWizardImage" UriSource="../assets/install.png"/>
</ResourceDictionary>

and modified the window constructor code so that if the separate assembly wasn't found, the resource from the standalone xaml file would be added instead:

if( File.Exists( resDllPath ) )
{
    // same as above
}
else
    Resources.Add( J4JWizardImageKey, TryFindResource( "DefaultWizardImage" ) );

This worked when the separate assembly was present. However, it failed when the separate assembly was left out, because the default image resource was not found. That may be because this Window isn't part of a WPF app; it's the UI for a Wix bootstrapper project.

It feels like there should be a simpler solution for what I'm trying to do, which I imagine is pretty common whenever a WPF library is designed (ie, you need some way to allow customization of bitmaps, but you also want to provide a default/fallback).


It sounds like you're only ever getting the initial value of the resource, as of when the XAML was parsed. If it's not there at that time, there's nothing; if it's a thing then, it's only ever that thing.

That is the behavior you'll see when you use StaticResource to retrieve the resources rather than DynamicResource . DynamicResource will update the target when the resource is replaced.

<Label Content="{DynamicResource MyImageSomewhere}" />
链接地址: http://www.djcxy.com/p/50440.html

上一篇: 任何人都可以解释如何/为什么要使用jQuery的CSS钩子?

下一篇: 在WPF窗口中包含可选资源