2011-04-12 21 views
8

Quiero cargar un DataTemplate en tiempo de ejecución usando XamlReader, pero arroja la excepción "Prefijo 'x' no se asigna a un espacio de nombres.""Prefijo 'x' no se asigna a un espacio de nombres"

Esta es la cadena XML que estoy pasando a 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> 

Este es el código que lo está leyendo:

ResourceDictionary dictionary = XamlReader.Parse(myXamlString) as ResourceDictionary; 

Aquí está la parte divertida, si añado x:Key="ValidationResponseTemplate" a la DataTemplate analiza sin excepciones. No puedo mantenerlo así, sin embargo, porque no puedo especificar el DataTemplate por clave en el propio .xaml del programa (no conocerá la plantilla hasta que se obtenga en el tiempo de ejecución).

El espacio de nombre x se define tanto en el propio .xaml del programa como en el fragmento de XML que estoy tratando de analizar.

Objetivo general: poder proporcionar nuevas plantillas de datos para cambiar la apariencia de la pantalla en tiempo de ejecución y para mostrar datos XML que el cliente no conocía en tiempo de compilación.

Respuesta

3

Encontré una manera de evitarlo: en lugar de tener XamlReader analizar una cadena, funcionó mejor si le di un XmlReader. El fragmento de XML con el DataTemplate definido en él era parte de un documento XML más grande que tenía todos sus espacios de nombres definidos en su raíz. Esto ya se había leído en un XDocument, y de la cual tomé el XElement con el ResourceDictionary definido en él. El nuevo código, parte de MainWindow.xaml.cs, se ve así:

ResourceDictionary dictionary = XamlReader.Load(myXElement.CreateReader()) as ResourceDictionary; 
this.Resources.MergedDictionaries.Add(dictionary); 

Esto arrojó una excepción diferente, donde no pudo resolver el tipo de (http://myschemas/MyProfile)Binding. Resulta que debe calificar los espacios de nombres de todo, incluidas las referencias {Binding ...}. Por lo que el fragmento XML tuvo que ser modificado para:

<xm:TextBox Text="{xm:Binding Path=MessageID}"/> 

Ahora XamlParser sabía que era un tipo Binding en el "http: //schemas.microsoft.com ..." espacio de nombres.

Cuestiones relacionadas