2009-02-11 5 views
13

Ich schaffe eine TextBox und eine Button dynamisch mit dem folgenden Code:WPF Wie erstelle ich ein Textfeld dynamisch und finde das Textfeld bei einem Klick?

Button btnClickMe = new Button(); 
btnClickMe.Content = "Click Me"; 
btnClickMe.Name = "btnClickMe"; 
btnClickMe.Click += new RoutedEventHandler(this.CallMeClick); 

someStackPanel.Childern.Add(btnClickMe); 

TextBox txtNumber = new TextBox(); 
txtNumber.Name = "txtNumber"; 
txtNumber.Text = "1776"; 

someStackPanel.Childern.Add(txtNumber); 

ich zu einem Click-Ereignis auf die Click Me Taste nach oben einhängen. Der click me-Button even wird korrekt ausgelöst. Ich kann jedoch nicht die TextBox finden, die ich dynamisch eingegeben habe. Hier

ist mein click me Veranstaltung:

protected void ClickMeClick(object sender, RoutedEventArgs e) 
{ 
    // Find the phone number 
    TextBox txtNumber = this.someStackPanel.FindName("txtNumber") as TextBox; 

    if (txtNumber != null) 
    { 
     string message = string.Format("The number is {0}", txtNumber.Text); 

     MessageBox.Show(message);  
    } 
    else 
    { 
     MessageBox.Show("Textbox is null"); 
    } 
} 

Wie finde ich die TextBoxtxtNumber?

+0

meinst du das.someStackPanel.FindName ("txtNumber")? – foson

+0

Danke ich reparierte es. Es funktioniert immer noch nicht. –

+0

Viele Fehler in dieser: (1) s/Childern/Kinder/ (2) Taste, um CallMeClick geroutet wird aber Code zeigt ClickMeClick (3) Taste in someStackPanel platziert wird, aber später nach dem in pnlCallMe Offensichtlich diese ist nicht der Code, den Sie ausführen. – hughdbrown

Antwort

14

Josh G hatte den Hinweis, dass dieser Code behoben: Verwenden Sie RegisterName().

Drei Vorteile hier:

  1. Nutzt eine Membervariable nicht den Verweis auf die dynamisch erstellte TextBox zu speichern.
  2. Kompiliert.
  3. Vollständiger Code.

    using System; 
    using System.Windows; 
    using System.Windows.Controls; 
    
    namespace AddControlsDynamically 
    { 
        public partial class Window1 : Window 
        { 
         public void Window_Loaded(object sender, RoutedEventArgs e) 
         { 
          GenerateControls(); 
         } 
         public void GenerateControls() 
         { 
          Button btnClickMe = new Button(); 
          btnClickMe.Content = "Click Me"; 
          btnClickMe.Name = "btnClickMe"; 
          btnClickMe.Click += new RoutedEventHandler(this.CallMeClick); 
          someStackPanel.Children.Add(btnClickMe); 
          TextBox txtNumber = new TextBox(); 
          txtNumber.Name = "txtNumber"; 
          txtNumber.Text = "1776"; 
          someStackPanel.Children.Add(txtNumber); 
          someStackPanel.RegisterName(txtNumber.Name, txtNumber); 
         } 
         protected void CallMeClick(object sender, RoutedEventArgs e) 
         { 
          TextBox txtNumber = (TextBox) this.someStackPanel.FindName("txtNumber"); 
          string message = string.Format("The number is {0}", txtNumber.Text); 
          MessageBox.Show(message); 
         } 
        } 
    } 
    
+0

Das klappt ganz gut. Ich ändere das zur akzeptierten Antwort, weil es das tut, was ich ursprünglich wollte. Das andere funktioniert auch gut, aber ich wollte keine Textbox erstellen und sie speichern. –

2

Gibt es eine Möglichkeit Sie das Textfeld ein Feld steuern in der Klasse statt einer Variablen in Ihrem Generator Methode machen kann

public class MyWindow : Window 
{ 
    private TextBox txtNumber; 

    public void Window_Loaded() 
    { 
     GenerateControls(); 
    } 

    public void GenerateControls() 
    { 
     Button btnClickMe = new Button(); 
     btnClickMe.Content = "Click Me"; 
     btnClickMe.Name = "btnClickMe"; 
     btnClickMe.Click += new RoutedEventHandler(this.CallMeClick); 
     someStackPanel.Childern.Add(btnClickMe); 
     txtNumber = new TextBox(); 
     txtNumber.Name = "txtNumber"; 
     txtNumber.Text = "1776"; 
     someStackPanel.Childern.Add(txtNumber); 
    } 

    protected void ClickMeClick(object sender, RoutedEventArgs e) 
    {  
     // Find the phone number  
     string message = string.Format("The number is {0}", txtNumber.Text);   
     MessageBox.Show(message); 
    } 
} 
+0

Das wird funktionieren. Aber gibt es keine Möglichkeit, es zu finden? Was passiert, wenn ich 10 Textfelder sage? Ist die Lösung, eine Liste zu erstellen und nur Linq zu verwenden, um sie zu finden? –

+0

Ich akzeptierte diese Antwort, weil es funktioniert, und wenn ich 10 Textfelder habe, kann ich eine Liste erstellen und sie in einer Liste finden. Danke. –

+0

Der Code kompiliert nicht: Childern, CallMeClick nicht definiert, etc. – hughdbrown

5

Eine andere Methode der zugehörige TextBox als Button Tag wenn Instanziierung sie gesetzt ist.

Auf diese Weise können Sie es zurück in Ereignishandler abrufen.

protected void ClickMeClick(object sender, RoutedEventArgs e) 
{ 
    Button btnClickMe = sender as Button; 
    if (btnClickMe != null) 
    { 
     TextBox txtNumber = btnClickMe.Tag as TextBox; 
     // ... 
    } 
} 
+0

Das funktioniert auch. –

3

Wenn Sie eine umfassende Suche über die visuelle Struktur der Kontrollen tun möchten, können Sie die VisualTreeHelper Klasse.

den folgenden Code können Sie durch alle visuellen Kinder einer Kontrolle iterieren:

for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parentObj); i++) 
{ 
    DependencyObject child = VisualTreeHelper.GetChild(parent, i); 

    if (child is TextBox) 
     // Do something 
} 

Wenn Sie unten in den Baum suchen wollen, sollten Sie diese Schleife rekursiv durchzuführen, etwa so:

public delegate void TextBoxOperation(TextBox box); 

public bool SearchChildren(DependencyObject parent, TextBoxOperation op) 
{ 
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++) 
    { 
     DependencyObject child = VisualTreeHelper.GetChild(parent, i); 

     TextBox box = child as TextBox; 

     if (box != null) 
     { 
      op.Invoke(box); 
      return true; 
     } 

     bool found = SearchChildren(child, op); 

     if (found) 
      return true; 
    } 
} 
4

Sie können Ihren ursprünglichen Click-Handler durch die Registrierung der Namen des Textfeldes an der Arbeit:

someStackPanel.RegisterName(txtNumber.Name, txtNumber); 

Dies wird dann können Sie Findnamen auf dem Stackpanel und finden Sie das TextBox nennen .

Verwandte Themen