duffmanseven
duffmanseven

Reputation: 175

Cannot create unknown type 'Canvas' when loading XAML control dynamically

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

Answers (1)

Clemens
Clemens

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

Related Questions