Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Prefix 'x' does not map to a namespace"

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.

like image 483
Chris Wenham Avatar asked Apr 12 '11 20:04

Chris Wenham


1 Answers

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.

like image 124
Chris Wenham Avatar answered Oct 17 '22 17:10

Chris Wenham