I want to load a DataTemplate at runtime using XamlReader
, but it's throwing the exception "Prefix 'x' does not map to a namespace."
This is the XML string I'm passing to XamlReader
:
<xm:ResourceDictionary
xmlns:xm="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:do="clr-namespace:MyLibrary.DataObjects;assembly=MyLibrary.DataObjects"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<xm:DataTemplate DataType="{x:Type do:ValidationResponse}">
<xm:StackPanel Orientation="Horizontal">
<xm:Label>MessageID</xm:Label>
<xm:TextBox Text="{Binding Path=MessageID}"/>
</xm:StackPanel>
</xm:DataTemplate>
</xm:ResourceDictionary>
This is the code that's reading it:
ResourceDictionary dictionary = XamlReader.Parse(myXamlString) as ResourceDictionary;
Here's the funny part, if I add x:Key="ValidationResponseTemplate"
to the DataTemplate it parses without any exceptions. I can't keep it that way, however, because I can't specify the DataTemplate by key in the program's own .xaml
(it won't know about the template until it gets fetched at runtime).
The x
namespace is defined in both the program's own .xaml
and in the fragment of XML I'm trying to parse.
Overall objective: be able to provide new DataTemplates to both change the appearance of the display at runtime, and to display XML data that the client did not know about at compile-time.
Found a way around it: rather than have XamlReader
parse a string, it worked better if I gave it an XmlReader
. The fragment of XML with the DataTemplate
defined in it was part of a larger XML document that had all its namespaces defined in its root. This had already been read into an XDocument
, and out of which I'd grabbed the XElement
with the ResourceDictionary
defined in it. The new code, part of MainWindow.xaml.cs
, looks like this:
ResourceDictionary dictionary = XamlReader.Load(myXElement.CreateReader()) as ResourceDictionary;
this.Resources.MergedDictionaries.Add(dictionary);
This threw a different exception, where it couldn't resolve the type of (http://myschemas/MyProfile)Binding
. It turns out that you need to qualify the namespaces of everything, including the {Binding ...}
references. So the XML fragment had to be amended to:
<xm:TextBox Text="{xm:Binding Path=MessageID}"/>
Now XamlParser knew that Binding
was a type in the "http://schemas.microsoft.com..." namespace.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With