2009-02-11 16 views
13

Sto creando un TextBox e un Button dinamicamente utilizzando il seguente codice:WPF come posso creare una casella di testo in modo dinamico e trovare la casella di testo su un pulsante?

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

collego ad un evento click al pulsante Click Me. Il pulsante "Fai clic su di me" viene persino attivato correttamente. Tuttavia non riesco a trovare lo TextBox inserito in modo dinamico.

Ecco il mio mi evento Click:

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

Come posso trovare il TextBoxtxtNumber?

+0

intendevi this.someStackPanel.FindName ("txtNumber")? – foson

+0

Grazie, l'ho risolto. Ancora non funziona. –

+0

Un sacco di errori di battitura in questo: (1) s/Childern/bambini/ (2) Pulsante viene indirizzato al CallMeClick ma il codice mostra ClickMeClick (3) pulsante è posizionato in someStackPanel ma poi viene ricercato in pnlCallMe Evidentemente, questo non è il codice che stai utilizzando. – hughdbrown

risposta

14

Josh G aveva l'indizio che ha risolto questo codice: utilizzare RegisterName().

tre vantaggi: qui

  1. Non fa uso di una variabile membro per salvare il riferimento al TextBox creato in modo dinamico.
  2. Compila.
  3. Codice completo.

    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

Questo funziona abbastanza bene. Lo cambio alla risposta accettata perché fa quello che volevo inizialmente. Anche l'altro funziona bene, ma non volevo creare una casella di testo e archiviarli. –

2

C'è qualche modo è possibile effettuare il controllo TextBox un campo nella classe invece di una variabile all'interno del vostro metodo di generatore

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

Funzionerà. Tuttavia non c'è modo di trovarlo? Cosa succede se ho 10 caselle di testo? È la soluzione per creare un elenco e basta usare Linq per trovarli? –

+0

Ho accettato questa risposta perché funziona, e se ho 10 caselle di testo posso creare una lista e trovarle in una lista. Grazie. –

+0

Il codice non viene compilato: Childern, CallMeClick non definito, ecc. – hughdbrown

5

Un altro metodo è quello di impostare l'associato TextBox come Button Tag quando instanciating loro.

btnClickMe.Tag = txtNumber; 

In questo modo è possibile recuperarlo nel gestore eventi.

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

Anche questo funziona. –

3

Se si vuole fare una ricerca completa attraverso la struttura visiva di controlli, è possibile utilizzare la classe VisualTreeHelper.

Utilizzare il seguente codice per scorrere tutti i bambini visive di un controllo:

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

    if (child is TextBox) 
     // Do something 
} 

Se si desidera effettuare la ricerca verso il basso nell'albero, si vuole eseguire questo ciclo in modo ricorsivo, in questo modo:

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

È possibile ottenere il vostro gestore di clic originale al lavoro registrando il nome della casella di testo:

someStackPanel.RegisterName(txtNumber.Name, txtNumber); 

Questo sarà quindi permetterà di chiamare FindName sulla StackPanel e trovare il controllo TextBox .

Problemi correlati