Yesterday, my fellow WPF Disciple Paul Stovell got me thinking about resolving XAML file paths.
As Paul points out, there doesn't appear to be an easy way to locate the URI for a XAML file. Internally, the generated .g.cs makes use of the path, as shown in the following excerpt:
public void InitializeComponent()
{
if (_contentLoaded)
{
return;
}
_contentLoaded = true;
System.Uri resourceLocater =
new System.Uri("/PageCollection;component/pages/page1.xaml", System.UriKind.Relative);
#line 1 "..\..\..\Pages\Page1.xaml"
System.Windows.Application.LoadComponent(this, resourceLocater);
#line default
#line hidden
}
But, how can we get our hands on it? What I’ve done is to incorporate the generation of XAML resource pack URIs into the T4 template I did a little while ago.
To demonstrate, I have created a dummy UserControl
in a subfolder in the sample application.
Image Figure: Dummy UserControl has a pack URI generated
The resulting output from the T4 template now enables us to determine the path to the XAML file in a safe way. The following excerpt shows the generated Pack URI:
namespace CSharpDesktopClrDemo.XamlMetadata.Folder1.Folder2.Metadata
{
public static class UserControl1XamlMetadata
{
public const string XamlPackUri
= @"/DanielVaughan.MetaGen.Demo;component/Folder1/Folder2/UserControl1.xaml";
}
}
Now we have this, we can write:
Uri uri = new Uri(CSharpDesktopClrDemo.XamlMetadata.Folder1.Folder2.Metadata
.UserControl1XamlMetadata.XamlPackUri, UriKind.Relative);
var control = System.Windows.Application.LoadComponent(uri)
as DanielVaughan.MetaGen.Demo.Folder1.Folder2.UserControl1;
No more magic string pack URIs!