1

I have a project containing a xaml ResourceDictionary that I wish to use outside of a FrameworkElement. The resource dictionary will contain a DataTemplate for a class local to the project to avoid polluting the app.xaml (as the project is a prism module, and will not always be present depending on config).

So, I have a test.xaml file with a Resource build action.

This is intended to supply the DataTemplate for a TestObject class.

In the TestObject class I have a GetTemplate() method

The following works:

DataTemplate GetTemplate()
{
    Uri uri = new Uri("MyProject;component/test.xaml", UriKind.Relative);

    var dict = new ResourceDictionary { Source = uri};

    return (DataTemplate)dict["TestObjectDataTemplate"];
}

This throws an exception when I assign the uri to the ResourceDictionary.Source property

DataTemplate GetTemplate()
{
    Uri uri = new Uri("/test.xaml", UriKind.Relative);

    var dict = new ResourceDictionary { Source = uri};

    return (DataTemplate)dict["TestObjectDataTemplate"];
}

The second example fails as the /test.xaml can't be found in the local assembly. Why would I need to access it with "ReferencedAssembly;component/test.xaml" ?

In this instance, does local assembly mean the executing assembly or the assembly the code/resource is part of?

Edit: Updated to reflect the actual issue.

LukeN
  • 1,698
  • 15
  • 29

2 Answers2

2

Try UriKind.RelativeOrAbsolute.

More clearly like.

    DataTemplate GetTemplate()
    {           
        ResourceDictionary resource = new ResourceDictionary()
        {
            Source = new Uri(@"/AssemblyFullName;component/test.xaml", UriKind.RelativeOrAbsolute)
        };

        return (DataTemplate)resource["TestObjectDataTemplate"];
    }

Edit:

In this instance, does local assembly mean the executing assembly or the assembly the code/resource is part of?

Say for example:
You have two projects Project A and Project B.

You are using Project A as reference in Project B

Now, if you want to use the resource like this /test.xaml. Then, this resource should reside in the Project B. Since, it is the executing assembly. [It will be available for both Project A as well as Project B. You could use the above mentioned syntax. like /test.xaml]

If you want the resource to be defined and used inside Project A. Then, you should use "/ProjectA;component/test.xaml" because it is not the current executing assembly. [It will be available for both Project A as well as Project B. You have to use "/ProjectA;component/test.xaml" this to access in both the projects]

Prince Ashitaka
  • 8,623
  • 12
  • 48
  • 71
  • I've edited the question to describe the problem more accurately. A relative uri works fine, the issue is that I have to refer to name of the assembly, despite the msdn docs implying that a "local assembly" shouldn't need this. – LukeN Oct 29 '10 at 09:41
  • This is it. The problem is that http://msdn.microsoft.com/en-us/library/aa970069.aspx says local assembly and not executing assembly. I've since discovered that someone else found it misleading as well - http://geekswithblogs.net/NewThingsILearned/archive/2008/04/30/pack-uri-authority---local-assembly--executable.aspx whereas in your example what I expected was that if I tried to load a Project A reference in code that lives in Project A, I wouldn't need to specify the name. On reflection, I understand why you might want this behaviour, but it was poorly described. – LukeN Nov 11 '10 at 05:40
1

Setting the Source attr works, I successfully used it in many projects.
Your Uri might be wrong. You should try a fully qualified pack Uri, like :

dict.Source = new Uri("pack://application:,,,/test.xaml");

If your test.xaml file is not in the project root, be sure to set its path correctly.

Aurelien Ribon
  • 7,548
  • 3
  • 43
  • 54