получение необъявленного префикса при динамическом создании объекта xaml - PullRequest
3 голосов
/ 21 февраля 2011

Черт возьми, я сейчас пытаюсь динамически создать несколько объектов в коде.Это было успешно до того момента, когда я хочу идентифицировать элемент, например. Здесь я создаю объект (эллипс с тенью)

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: Nameдля объекта программно?

Спасибо,

Ответы [ 2 ]

5 голосов
/ 21 февраля 2011

Может ли кто-нибудь указать мне правильное направление для ссылки на динамически созданный объект в подобном сценарии или как правильно определить x: Name для объекта программно?

Вы не можете напрямую ссылаться на "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;
}
2 голосов
/ 21 февраля 2011

Нет, нет, нет, нет, нет!

НИКОГДА использовать манипуляции со строками для создания XML. НИКОГДА.

Всегда используйте XML API для манипулирования XML. Любой из API-интерфейсов XML понимает пространства имен, чего вы явно не понимаете.


Следующие компилируются, но не были проверены:

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());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...