在动态创建xaml对象时接收未声明的前缀

时间:2011-02-21 18:46:21

标签: c# wpf silverlight

全部,我正在尝试在代码中动态创建一些对象。这已经成功,直到我想要识别元素的地方为例 在这里,我创建了一个对象(一个带阴影的椭圆)

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;
    }

我想要做的是创建对象后我希望能够使用VisualTreeHelper找到父对象。

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

任何人都可以指出我在这样的场景中引用动态创建的对象的正确方向,或者如何以编程方式正确定义x:对象的名称?

谢谢,

2 个答案:

答案 0 :(得分:5)

  

有人能指出我在这样的场景中引用动态创建的对象的正确方向,或者如何以编程方式正确定义x:对象的名称?

您无法使用动态生成的类型直接引用“myellipse”。编译器在编译时将x:Name转换为类型 - 因为您在运行时加载它,它将不存在。

相反,您可以创建一个“myellipse”变量,并让您的动态生成例程设置它:

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;
}

话虽如此,我建议不要使用这样的字符串构建椭圆。您可以直接创建椭圆类,然后添加效果。在这种情况下,您无需使用XamlReader来解析字符串。

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;
}

答案 1 :(得分:2)

不,不,不,不,不!

从不 使用字符串操作来创建XML。 NEVER。

始终使用XML API来操作XML。任何XML API都能理解名称空间,但您显然不了解。


以下编译但尚未经过测试:

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());