XAML (WPF) designer does not resolve app resources in a consistent or meaningful way

Viewed 1856

I've often been troubled by designer issues where the XAML designer (WPF's "xdesproc") will display my controls in one way, but they will be displayed in a totally different way at run time. Often these differences come down to the fact that the static resources used at runtime (at the application level) are not the ones used in the designer.

This happens primarily when a large solution is made up of a number of projects - most of which are user control libraries, and a few of them are startup projects (applications, test harnesses, etc).

While using VS to edit a usercontrol in one of the libraries, I've discovered a trick from Blend whereby you can introduce the "DesignTimeResources.xaml" file in a project and visual studio will "respect" it and merge these resources as a supplement to the ones in the user control itself (as if they had been found in the logical tree for that usercontrol).

I thought that this trick would be sufficient so that I would be able to forgo the need for application-level resources in the designer. However, the "DesignTimeResources.xaml" doesn't solve all my problems. Nor does xdesproc consider this as a sufficient source of application-level resources either (ie. xdesproc might consider loading this both as its application-level resources and in the logical tree of the user control if it wanted to.)

After snooping on xdesproc with procmon, I find it behaves in very unusual ways in order to find the stuff that it wants to use for its application-level resources. The search mechanism that it uses does not seem very well-defined. If one is not careful, it either neglects to establish any application-level resources at all, or it picks randomly from one of the projects it might find in the outer solution (a project which is possibly not relevant to the usercontrol library in any way, but is found and is used because it contains a project item which happens to be an "Application/").

Can someone tell me if there is supposed to be a well-defined way that the xdesproc finds application-level resources while editing a usercontrol? My work-around is a lot of obsessive tinkering that involves unloading projects. I temporary unload all projects from my solution that have "Application" elements, with the exception of one. Unless I do this, xdesproc is liable to randomly pick one of them out and start happily using it for its app-level resources. It doesn't seem to limit itself to the current startup project in the VS IDE.

I would appreciate any pointers to help me understand what xdesproc thinks it should be using for its app resources. I suspect it was programmed to be "smart" and "just work". And it probably does work in many cases, except when it doesn't.

3 Answers

To fix this type of issue, I have not made use of "DesignTimeResources.xaml" (I didn't know that was a thing).

When I have assemblies with controls that I would like to use the designer for, I make the App.xaml (and App.xaml.cs) in the root (eg. copy from a startup-assembly). I have the BuildAction set to "Page".

In the App.xaml I reference the resource(s) which are expected to be loaded when the assembly is used.

We have som daisy-chained assemblies, so each assembly with controls has a "AllDictionaries.xaml" resource dictionary, that can be referenced by the assemblies, which use it.

Example of App.xaml content:

<Application x:Class="RD.Controls.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/RD.Controls;component/AllDictionaries.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

Having the App.xaml file in the assembly ensures the 'main dictionary' is loaded, which references any other needed resources from references assemblies.

Related