Dynamic and Immutable UIElement Arrays
I have a WrapPanel
that contains multiple Canvas
of the same size. Each Canvas
has some UIElement
s (i.e. TextBox
, TextBlock
, Button
s etc) as children. The creation of each Canvas
(including its UIElement
children) and the number of Canvas
to be created are all done in run-time code behind (no XAML).
Initially I did the following, which works:
// 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]);
}
The above code is straight forwards works OK - Until I implement add, minus and destroy buttons where I could
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`)
If I process some combination of the above 3 actions, I could easily create UIElements of the same index or create Canvas that goes out of the range of what it had been declared initially.
I looked into List however, each Canvas have different properties (each also has UIElement Children with different properties) and I can't figure out how List would solve it. A way for me to go around that is to declare a super large Array size for Canvas (e.g. Canvas[] cv = new Canvas[99999] but I though that's not very efficient.
Also, if I use List, how could I change properties of a specific UIElement after the they are generated? E.g. If i add 10 Canvas and add to List, and after they are all generated, I need to select the 5th Canvas and change a TextBox.Text, how do I access it like I did in an Array (i.e. tb[5].Text = "Hello")?
Can anyone show me some approaches to this problem?
Just a direct translation on how to do this with a list instead below. Given your code I don't know why you want to keep track of the canvas and textbox'es in a list - you can just access the children collection of the WrapPanel
directly instead - let's assume you do need these separate collections for now.
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);
}
Edit for added comment:
E.g. If i add 10 Canvas, and after they are all generated, I need to select the 5th Canvas and change a TextBox.Text, how do I access it like I did in an Array (i.e. tb[5].Text = "Hello")?
You can just access the children directly. You know you only added Canvas
elements to your WrapPanel
. So you could do (wp is the WrapPanel
again):
TextBox textbox = (wp.Children[5] as Canvas).Children[0] as TextBox;
textbox.Text = "Hello";
Just operate directly on the WrapPanel
's Children collection.
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);
}
}
}
精彩评论