代码之家  ›  专栏  ›  技术社区  ›  David Basarab

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

  •  15
  • David Basarab  · 技术社区  · 16 年前

    我正在创建一个 TextBox Button 动态使用以下代码:

    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 按钮“单击我”按钮甚至可以正确触发。但是我找不到 我动态地进入。

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

    我怎样才能找到那辆车 txtNumber ?

    5 回复  |  直到 13 年前
        1
  •  17
  •   hughdbrown    16 年前

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

    这里有三个好处:

    1. 不使用成员变量保存对动态创建的文本框的引用。
    2. 完整的代码。

      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);
              }
          }
      }
      
        2
  •  7
  •   Michaël Carpentier    16 年前

    另一种方法是设置关联的 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;
            // ...
        }
    }
    
        3
  •  5
  •   Josh G    16 年前

    通过注册文本框的名称,可以使原始的单击处理程序正常工作:

    someStackPanel.RegisterName(txtNumber.Name, txtNumber);
    

    这将允许您调用StackPanel上的FindName并找到文本框。

        4
  •  4
  •   Josh G    16 年前

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

    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;
        }
    }
    
        5
  •  3
  •   bendewey    16 年前

    有没有办法让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);
        }
    }