Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF UserControl cannot find XAML resource in referencing project

In my WPF project i keep a user control in a separate library project. The user control accesses resources in a separate XAML file, like this:

<UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="/Resources/ViewResources.xaml" />
        </ResourceDictionary.MergedDictionaries>
        <!-- Local styles here -->
    </ResourceDictionary>
</UserControl.Resources>

The resource file, ViewResources.xaml, resides in a folder in the control library project named Resources. It has the default build action (Page) and custom tool (MSBuild:Compile).

The problem is when I reference the control library in my WPF application and use the user control. At runtime, I get the following XamlParseException:

Set property 'System.Windows.ResourceDictionary.Source' threw an exception.

...which wraps the IOException:

Cannot locate resource 'resources/viewresources.xaml'.

How can I fix this? I have tried to change the resource file's build action to "content" and have it copied to the output directory (that works for files and similar "dumb" resources). But to no avail. Also, it doesn't work property in the user control then.

Is there a better way to specify the path?

Will I have to move the resource file to the application project (I'd rather not, as it belongs in the user control's domain).

like image 907
Tor Haugen Avatar asked Sep 20 '10 00:09

Tor Haugen


4 Answers

Found it.

Turns out there is a better way to specify the path, Pack URIs. I changed the XAML to the following:

<UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="pack://application:,,,/RoutingManager;component/Resources/ViewResources.xaml" />
        </ResourceDictionary.MergedDictionaries>
        <!-- Local styles here -->
    </ResourceDictionary>
</UserControl.Resources>

and that fixed it.

like image 116
Tor Haugen Avatar answered Oct 06 '22 11:10

Tor Haugen


I thought it was worth posting this just in case anyone else is struggling with the same problem, as I've spent over two hours fighting with syntax, etc. only to find that the solution was dead simple, but not that apparent: When referencing a packed resource from another control library, it seems to work fine at design time, and even compiles without error, but fails at runtime with the 'Set property 'System.Windows.ResourceDictionary.Source' threw an exception' error. It turns out that simply referencing the resource assembly from your control library is not enough, you ALSO need to add a REFERENCE to the assembly containing the resource dictionary in you main application assembly, else it seems it does not get compiled into the application. (i.e. Startup Application (the one with app.xaml) -> Add Reference -> select assembly with referenced resource file/s).

Hope this helps!

like image 20
AdrianD Avatar answered Oct 06 '22 11:10

AdrianD


In my case I had the ResourceDictionary and the UserControl on the same Library, but separate from the main application. What worked for me was specifying the name of the assembly in the format Adam suggested in the comment AND I had to change the ResourceDictionary in the project from Embedded Resource to Page. I didn't try using the pack:// format, but I assume it would work too.

<ResourceDictionary Source="/AssemblyName;component/Assets/MyResource.xaml"/>
like image 7
AlexDev Avatar answered Oct 06 '22 09:10

AlexDev


I had the same error (IOException - file not found), which cost me a day of my life that I'll never get back.

Using neither the simpler "/assemblyname..." nor the "pack://...." syntax worked for me.

I was referencing the resource assembly in my main assembly correctly.

The error disappeared when I changed my xaml resource file Build Action property to "Resource", as mentioned above.

However, I then encountered a XamlParseException at this line:

<ImageBrush x:Key="WindowBackground" ImageSource="Images/gradient.png" />

(which I had hand-typed).

This left the xaml resource file I was trying to include with effectively an invalid dependency.

Oddly the fix was to delete the ImageSource property I had typed, re-insert it BUT select the image from the pulldown menus that appear as a result.

Even though the resulting line appears exactly the same, it clearly isn't.

Starting to dislike WPF (VS2013), but hope this helps.

:0/

like image 2
Ian Avatar answered Oct 06 '22 09:10

Ian