简体   繁体   中英

receiving undeclared prefix when dynamically creating a xaml object

Hell all, I am currently trying to create a few object dynamically in code. This has been successful up to the point to where I want to identify the element for example Here I create the object ( an ellipse with a drop shadow)

public MainPage()
    {
        InitializeComponent();
        Loaded += new RoutedEventHandler(MainPage_Loaded);
    }

    void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        var element = CreateEllipse();
        LayoutRoot.Children.Add(element);
    }

    public Ellipse CreateEllipse()
    {
        StringBuilder xaml = new StringBuilder();
        string ns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation";
        xaml.Append("<Ellipse ");
        xaml.Append(string.Format("xmlns='{0}'", ns));
        xaml.Append(" x:Name='myellipse'"); //causes the exception
        xaml.Append(" Margin='50 10 50 10'");
        xaml.Append(" Grid.Row='0'");
        xaml.Append(" Fill='#FD2424FF'");
        xaml.Append(" Stroke='Black' >");
        xaml.Append("<Ellipse.Effect>");
        xaml.Append("<DropShadowEffect/>");
        xaml.Append(" </Ellipse.Effect>");
        xaml.Append(" </Ellipse>");
        var ellipse = (Ellipse)XamlReader.Load(xaml.ToString());
        return ellipse;
    }

What I want to do is after the object is created I want to be able to locate the parent objects using VisualTreeHelper.

public void button1_Click(object sender, RoutedEventArgs e)
    {
        DependencyObject o = myellipse;
        while ((o = VisualTreeHelper.GetParent(o)) != null)
        {
            textBox1.Text = (o.GetType().ToString());
        }
    }

Can anyone point me in the right direction for referencing a dynamically created object in a scenario like this or how to properly define x:Name for an object programatically?

Thank you,

Can anyone point me in the right direction for referencing a dynamically created object in a scenario like this or how to properly define x:Name for an object programatically?

You can't reference "myellipse" directly like this with dynamically generated types. The compiler converts the x:Name to a type at compile time - since you're loading this at runtime, it will not exist.

You could, instead, make a "myellipse" variable, and have your dynamic generation routine set it:

void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    var element = CreateEllipse();
    LayoutRoot.Children.Add(element);
}

private Ellipse myEllipse; 
public Ellipse CreateEllipse()
{
    StringBuilder xaml = new StringBuilder();
    string ns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation";
    xaml.Append("<Ellipse ");
    xaml.Append(string.Format("xmlns='{0}'", ns));
    xaml.Append(" Margin='50 10 50 10'");
    xaml.Append(" Grid.Row='0'");
    xaml.Append(" Fill='#FD2424FF'");
    xaml.Append(" Stroke='Black' >");
    xaml.Append("<Ellipse.Effect>");
    xaml.Append("<DropShadowEffect/>");
    xaml.Append(" </Ellipse.Effect>");
    xaml.Append(" </Ellipse>");
    this.myEllipse = (Ellipse)XamlReader.Load(xaml.ToString());

    return this.myEllipse;
}

That being said, I would recommend not building the ellipse using strings like this. You could just create the ellipse class directly, and add the effect. You don't need to use XamlReader to parse a string in this case.

private Ellipse myEllipse; 
public Ellipse CreateEllipse()
{
     this.myEllipse = new Ellipse();
     this.myEllipse.Effect = new DropShadowEffect();
     Grid.SetRow(this.myEllipse, 0);
     // Set properties as needed

     return this.myEllipse;
}

No, no, no, no, no!

NEVER use string manipulation to create XML. NEVER.

Always use an XML API to manipulate XML. Any of the XML APIs understand namespaces, which you clearly do not.


The following compiles but has not been tested:

XNamespace ns =
    "http://schemas.microsoft.com/winfx/2006/xaml/presentation";
XNamespace xns =
    "http://schemas.microsoft.com/winfx/2006/xaml";
var ellipse = new XElement(
    ns + "Ellipse",
    new XAttribute(XNamespace.Xmlns + "x", "http://schemas.microsoft.com/winfx/2006/xaml"),
    new XAttribute(xns + "Name","myellipse"),
    new XAttribute("Margin","50 10 50 10"),
    new XAttribute("Grid.Row", "0"),
    new XElement(ns +"Ellipse.Effect",
        new XElement(ns +"DropShadowEffect")));
return
    (Ellipse)
    XamlReader.Load(ellipse.CreateReader());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM