Reputation: 175
I am trying to build a WPF user control that loads Canvas elements dynamically. Stored in a database is a template of Xaml canvas drawing that I want to call in a load into a Viewbox.
I'm having trouble when executing the Xamlreader.Load method where an exception is thrown saying that the parent element ("Canvas") is an unknown type. I've done some research and it was recommended to define the LocalAssembly inside a xamlXmlreaderSettings object and pass it into the reader.
My code is as follows:
UserControl1.xaml.cs:
StringReader stringReader = new StringReader(cart.svgtemplate); //this a string retrieved from DB that has the XAML
XmlReaderSettings settings = new XmlReaderSettings { NameTable = new NameTable() };
XmlNamespaceManager xmlns = new XmlNamespaceManager(settings.NameTable);
xmlns.AddNamespace("x", "http://schemas.microsoft.com/winfx/2006/xaml");
XmlParserContext context = new XmlParserContext(null, xmlns, "", XmlSpace.Default);
XmlReader xmlReader = XmlReader.Create(stringReader,settings, context);
var xamlXmlReaderSettings = new XamlXmlReaderSettings()
{
LocalAssembly = System.Reflection.Assembly.GetExecutingAssembly()
};
XamlXmlReader xamlXmlReader = new XamlXmlReader(xmlReader, xamlXmlReaderSettings);
this.viewbox.Child = (UIElement)System.Windows.Markup.XamlReader.Load(xamlXmlReader);
XAML from DB is
<Canvas x:Name="canvas" Width="100" Height="90" RenderTransformOrigin="0.5,0.5" Background="{DynamicResource {x:Static SystemColors.ControlLightBrushKey}}">
<Rectangle Canvas.Left="1" Canvas.Top="1" Width="95" Height="80" Name="rect442" Fill="#ffff00"/>
<Rectangle Canvas.Left="1" Canvas.Top="1" Width="1.75" Height="80" Name="rect446" Fill="#0000ff"/>
<Rectangle Canvas.Left="2.75" Canvas.Top="79.25" Width="92.5" Height="1.75" Name="rect450" Fill="#0000ff"/>
<Rectangle Canvas.Left="94.25" Canvas.Top="1" Width="1.75" Height="80" Name="rect454" Fill="#0000ff"/>
<Rectangle Canvas.Left="2.75" Canvas.Top="42.5" Width="72" Height="1.75" Name="rect458" Fill="#0000ff"/>
<Rectangle Canvas.Left="74.75" Canvas.Top="1" Width="1.75" Height="78.25" Name="rect462" Fill="#0000ff"/>
....
UserControl1.xaml:
<UserControl x:Name="userControl" x:Class="Smart_Cart_Sample.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Smart_Cart_Sample"
mc:Ignorable="d"
d:DesignHeight="700" d:DesignWidth="800">
<Viewbox x:Name="viewbox" Stretch="Fill" Width="{Binding Width, ElementName=userControl}" Height="{Binding Height, ElementName=userControl}" RenderTransformOrigin="0.5,0.5">
</Viewbox>
</UserControl>
I'm unsure if the how am referring the executing assembly is the proper way to do it. I would want the XAML being read in to use the Local Assembly of the calling control. I appreciate all the insight I can get on this.
Upvotes: 0
Views: 807
Reputation: 128146
The default namespace is missing:
var settings = new XmlReaderSettings { NameTable = new NameTable() };
var xmlns = new XmlNamespaceManager(settings.NameTable);
// here
xmlns.AddNamespace("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
xmlns.AddNamespace("x", "http://schemas.microsoft.com/winfx/2006/xaml");
var context = new XmlParserContext(null, xmlns, "", XmlSpace.Default);
var xmlReader = XmlReader.Create(stringReader, settings, context);
viewbox.Child = (UIElement)System.Windows.Markup.XamlReader.Load(xmlReader);
Upvotes: 3