WPF如何动态创建文本框并在按钮单击时找到文本框?

我正在使用以下代码动态创建TextBoxButton

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

我点击了Click Me按钮的点击事件。 单击我按钮甚至被正确触发。 但是我找不到动态输入的TextBox

这是我点击我的活动:

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

如何找到TextBox txtNumber

Josh G有修复此代码的线索:使用RegisterName()。

这里有三个好处:

  1. 不使用成员变量来保存对动态创建的TextBox的引用。
  2. 编译。
  3. 完整的代码。

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

另一种方法是在实例化时将关联的TextBox设置为Button Tag

 btnClickMe.Tag = txtNumber; 

这样您就可以在事件处理程序中将其检索回来。

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

您可以通过注册文本框的名称来使原始的单击处理程序起作用:

 someStackPanel.RegisterName(txtNumber.Name, txtNumber); 

这将允许您在StackPanel上调用FindName并找到TextBox。

如果要通过可视控件树进行全面搜索,可以使用VisualTreeHelper类。

使用以下代码迭代控件的所有可视子项:

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

如果要向下搜索树,则需要递归执行此循环,如下所示:

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

有没有什么方法可以让TextBox控件成为类中的字段而不是生成器方法中的变量

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