visual uso tipos propiedades grupos elementos dialogo cuadros cuadro abrir c# .net wpf textbox mouseevent

c# - uso - WPF ¿cómo creo un cuadro de texto de forma dinámica y encuentro el cuadro de texto con un clic de botón?



tipos de cuadros de dialogo (5)

Estoy creando un TextBox y un Button dinámicamente usando el siguiente código:

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

Me conecto a un evento de clic para hacer clic en el botón Click Me . El botón "clic en mí" incluso se dispara correctamente. Sin embargo, no puedo encontrar el TextBox que TextBox dinámicamente.

Aquí está mi clic en mi evento:

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

¿Cómo puedo encontrar TextBox txtNumber ?


¿Hay alguna manera de que el control TextBox sea un campo en su clase en lugar de una variable dentro de su método generador?

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


Josh G tenía la clave que corrigió este código: use RegisterName ().

Tres beneficios aquí:

  1. No utiliza una variable miembro para guardar la referencia al TextBox creado dinámicamente.
  2. Compila
  3. Código 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); } } }


Otro método es establecer el TextBox asociado como Button Tag al instanciarlos.

btnClickMe.Tag = txtNumber;

De esta forma, puedes recuperarlo en el controlador de eventos.

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


Puede obtener su manejador de clic original para trabajar registrando el nombre del cuadro de texto:

someStackPanel.RegisterName(txtNumber.Name, txtNumber);

Esto le permitirá llamar a FindName en el StackPanel y encontrar el TextBox.


Si desea hacer una búsqueda exhaustiva a través del árbol visual de controles, puede usar la clase VisualTreeHelper.

Use el siguiente código para iterar a través de todos los elementos secundarios visuales de un control:

for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parentObj); i++) { DependencyObject child = VisualTreeHelper.GetChild(parent, i); if (child is TextBox) // Do something }

Si desea buscar en el árbol, querrá realizar este bucle recursivamente, así:

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