Динамические и неизменяемые массивы UIElement - PullRequest
2 голосов
/ 04 апреля 2011

У меня есть WrapPanel, который содержит несколько Canvas одинакового размера. Каждый Canvas имеет несколько UIElement с (то есть TextBox, TextBlock, Button с и т. Д.) В качестве детей. Создание каждого Canvas (включая его UIElement дочерние элементы) и число Canvas, которые должны быть созданы, выполняются в коде времени выполнения (без XAML).

Изначально я сделал следующее, что работает:

// declare as class properties, so all function can access them
WrapPanel wp = new WrapPanel();
Canvas[] cv = new Canvas[500];
TextBox[] tb = new TextBox[500];

// A function (e.g. a Button_Click event) that generates multiple Canvas in a WrapPanel
for (int i = 0; i<myInt; i++)
{
cv[i] = new Canvas();
tb[i] = new TextBox();
cv[i].Children.Add(tb[i]);
wp.Children.Add(cv[i]);
}

Вышеприведенный код работает нормально. До тех пор, пока я не реализую кнопки добавления, минуса и уничтожения, где я мог бы

1. Add an additional `Canvas` on a click event
2. Remove the last `Canvas` on a click event
3. Destroy a specific `Canvas` in the `WrapPanel` on a click event (may ba a little cross icon in each `Canvas`)

Если я обработаю какую-либо комбинацию из трех вышеуказанных действий, я мог бы легко создать элементы UIE с тем же индексом или создать Canvas, выходящий за пределы того, что было объявлено изначально.

Я просмотрел List , однако, у каждого Canvas есть разные свойства (у каждого также есть UIElement Children с разными свойствами), и я не могу понять, как List это решит. Для меня способ обойти это - объявить очень большой размер массива для Canvas (например, Canvas [] cv = new Canvas [99999] , но я думаю, что это не очень эффективно.

)

Кроме того, если я использую List, как я могу изменить свойства определенного UIElement после того, как они сгенерированы? Например. Если я добавлю 10 Canvas и добавлю в список, и после того, как все они будут сгенерированы, мне нужно выбрать 5-й холст и изменить TextBox.Text, как мне получить к нему доступ, как я это делал в массиве (т.е. tb [5] .Text = "Привет")?

Может кто-нибудь показать мне некоторые подходы к этой проблеме?

Ответы [ 2 ]

3 голосов
/ 04 апреля 2011

Просто прямой перевод о том, как это сделать, с помощью списка ниже. Учитывая ваш код, я не знаю, почему вы хотите отслеживать холст и текстовые поля в списке - вместо этого вы можете просто получить доступ к дочерней коллекции WrapPanel - давайте предположим, что вам сейчас нужны эти отдельные коллекции .

 WrapPanel wp = new WrapPanel();
 List<Canvas> cvList = new List<Canvas>();
 List<TextBox> tbList = new List<TextBox>();

 public void Init()
{

    int myInt = 500;
    // in a function (e.g. a Button_Click event) to generate the multiple Canvas in a WrapPanel
    for (int i = 0; i < myInt; i++)
    {
        Canvas cv = new Canvas();
        TextBox tb = new TextBox();
        cv.Children.Add(tb);
        wp.Children.Add(cv);

        cvList.Add(cv);
        tbList.Add(tb);
    }
}


public void AddCanvas()
{
    Canvas cv = new Canvas();
    TextBox tb = new TextBox();
    cv.Children.Add(tb);
    wp.Children.Add(cv);
    cvList.Add(cv);
    tbList.Add(tb);
}

public void RemoveCanvas()
{
        wp.Children.RemoveAt(wp.Children.Count-1);
        cvList.RemoveAt(cvList.Count - 1);
        tbList.RemoveAt(cvList.Count - 1);
}

Редактировать для добавления комментария:

например. Если я добавлю 10 холст, и после они все созданы, мне нужно выберите 5-й холст и измените TextBox.Text, как я могу получить к нему доступ, как Я сделал в массиве (то есть tb [5] .Text = "Привет")

Вы можете просто получить доступ к детям напрямую. Вы знаете, что только добавили Canvas элементов к вашему WrapPanel. Так что вы могли бы сделать (wp это снова WrapPanel):

TextBox textbox = (wp.Children[5] as Canvas).Children[0] as TextBox;
textbox.Text = "Hello";
1 голос
/ 04 апреля 2011

Просто работайте непосредственно с коллекцией WrapPanel Children.

public partial class MainWindow : Window
{        

    public MainWindow()
    {
        InitializeComponent();
        AddCanvasToWrapPanel(this.TestWrapPanel);
        RemoveLastCanvasFromWrapPanel(this.TestWrapPanel);
        AddCanvasToWrapPanel(this.TestWrapPanel);
        DestroyCanvasAtWrapPanelIndex(this.TestWrapPanel, 0);

    }

    private void AddCanvasToWrapPanel(WrapPanel wp)
    {
        TextBox t = new TextBox();
        Canvas c = new Canvas();
        c.Children.Add(t);
        wp.Children.Add(c);
    }

    private void RemoveLastCanvasFromWrapPanel(WrapPanel wp)
    {
        wp.Children.RemoveAt(wp.Children.Count - 1);
    }

    private void DestroyCanvasAtWrapPanelIndex(WrapPanel wp, int index)
    {
        wp.Children.RemoveAt(index);
    }


}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...