2011-04-04 5 views
2

J'ai un WrapPanel qui contient plusieurs Canvas de la même taille. Chaque Canvas a quelques UIElement s (c'est-à-dire TextBox, TextBlock, Button s etc.) comme enfants. La création de chaque Canvas (y compris ses enfants UIElement) et le nombre de Canvas à créer sont tous effectués dans le code d'exécution derrière (aucun XAML).Tableaux UIElement dynamiques et immuables

Au départ, je l'ai fait ce qui suit, qui fonctionne:

// 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]); 
} 

Le code ci-dessus est fonctionne directement vers l'avant OK - Jusqu'à ce que je mets en œuvre ajouter, moins et détruire les boutons où je pouvais

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`) 

Si je traiter une combinaison des 3 actions ci-dessus, je pourrais facilement créer des UIElements du même index ou créer des Canvas qui sortent de la portée de ce qui avait été déclaré initialement.

J'ai regardé dans Liste Cependant, chaque Canvas a des propriétés différentes (chacun a aussi UIElement Children avec des propriétés différentes) et je ne peux pas comprendre comment List le résoudrait. Une façon pour moi de faire le tour qui est de déclarer une super grande taille Array pour Canvas (par exemple Canvas [] cv = new toile [99999] mais je pensais que ce n'est pas très efficace.

De plus, si j'utilise la liste , comment pourrais-je changer les propriétés d'un UIElement spécifique après qu'elles soient générées? Par exemple si j'ajoute 10 Canvas et ajoute à la liste, et après qu'elles soient toutes générées, je dois choisir le 5ème Canvas et changer un TextBox.Text, comment faire J'AccessIT comme je l'ai fait dans un tableau (c.-à-tb [5] .Text = « Bonjour »)?

quelqu'un peut-il me montrer des approches de ce problème?

+0

Si vous avez besoin d'un tableau qui peut rétrécir/grossir, vous demandez une liste. Pouvez-vous expliquer pourquoi une liste ne fonctionnerait pas dans votre cas? –

+0

@vanja, j'ai édité ma question qui espère devrait clarifier le problème. – KMC

+0

1. N'utilisez pas de listes parallèles. Faites un type qui représente chaque entrée en entier, et gardez une seule liste de ce type, pas plusieurs listes où chacune n'a qu'une partie de l'histoire. 2. Vous devriez vraiment regarder dans MVVM. –

Répondre

3

Juste une traduction directe sur la façon de faire avec une liste dans lieu ci-dessous. Étant donné votre code, je ne sais pas pourquoi vous voulez garder une trace de la zone de texte et des zones de texte dans une liste - vous pouvez simplement accéder directement à la collection enfants du WrapPanel - supposons que vous ayez besoin de ces collections séparées pour l'instant.

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

Modifier pour commentaire ajouté:

Par ex Si j'ajoute 10 Canvas, et après ils sont tous générés, je dois sélectionner le 5ème toile et changer un TextBox.Text, comment puis-je accéder comme je l'ai fait dans un tableau (c.-à-tb [5] .Text = "Bonjour")?

Vous pouvez simplement accéder aux enfants directement. Vous savez que vous avez seulement ajouté des éléments Canvas à votre WrapPanel. Ainsi, vous pouvez faire (wp est le nouveau WrapPanel):

TextBox textbox = (wp.Children[5] as Canvas).Children[0] as TextBox; 
textbox.Text = "Hello"; 
+0

Je suis avec @BrokenGlass - semble logique dans ce cas que vous voulez juste être en mesure de gérer les enfants dans la collection de WrapPanel. – dugas

+0

merci. Mais alors comment pourrais-je changer les propriétés d'un UIElement spécifique? Par exemple. Si j'ajoute 10 Canvas, et après qu'ils soient tous générés, j'ai besoin de sélectionner le 5ème Canvas et de changer un TextBox.Text, comment y accéder comme je l'ai fait dans un Array (ie tb [5] .Text = "Hello")? – KMC

+0

@KMC - Canvas c = (Toile) wp.Children [4] obtiendrait la 5ème toile dans le WrapPanel. TextBox t = (TextBox) c.Children [0] obtiendrait la zone de texte. – dugas

1

Juste fonctionnent directement sur la collection Les enfants de WrapPanel.

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


} 
} 
Questions connexes