C# WPF如何动态创建文本框并在单击按钮时找到文本框?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/537073/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF how do I create a textbox dynamically and find the textbox on a button click?
提问by David Basarab
I am creating a TextBox
and a Button
dynamically using the following code:
我正在使用以下代码动态创建 aTextBox
和 a 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);
I hook up to a click event to the Click Me
button. The click me button even is fired correctly. However I cannot find the TextBox
I entered dynamically.
我将点击事件连接到Click Me
按钮。单击我按钮甚至被正确触发。但是我找不到TextBox
我动态输入的。
Here is my click me event:
这是我的点击我事件:
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");
}
}
How can I find the TextBox
txtNumber
?
我怎样才能找到TextBox
txtNumber
?
采纳答案by hughdbrown
Josh G had the clue that fixed this code: use RegisterName().
Josh G 有修复此代码的线索:使用 RegisterName()。
Three benefits here:
这里的三个好处:
- Doesn't use a member variable to save the reference to the dynamically created TextBox.
- Compiles.
Complete 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); } } }
- 不使用成员变量来保存对动态创建的 TextBox 的引用。
- 编译。
完整的代码。
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); } } }
回答by bendewey
Is there any way you can make the TextBox control a field in your class instead of a variable inside your generator method
有什么方法可以让 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);
}
}
回答by Micha?l Carpentier
Another method is to set the associated TextBox
as Button Tag
when instanciating them.
另一种方法是,设置相关联的TextBox
作为Button Tag
instanciating时它们。
btnClickMe.Tag = txtNumber;
This way you can retrieve it back in event handler.
这样您就可以在事件处理程序中检索它。
protected void ClickMeClick(object sender, RoutedEventArgs e)
{
Button btnClickMe = sender as Button;
if (btnClickMe != null)
{
TextBox txtNumber = btnClickMe.Tag as TextBox;
// ...
}
}
回答by Josh G
If you want to do a comprehensive search through the visual tree of controls, you can use the VisualTreeHelper class.
如果要通过控件的可视化树进行全面搜索,可以使用 VisualTreeHelper 类。
Use the following code to iterate through all of the visual children of a control:
使用以下代码遍历控件的所有可视子项:
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parentObj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(parent, i);
if (child is TextBox)
// Do something
}
If you want to search down into the tree, you will want to perform this loop recursively, like 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;
}
}
回答by Josh G
You can get your original click handler to work by registering the name of the text box:
您可以通过注册文本框的名称来使原始点击处理程序工作:
someStackPanel.RegisterName(txtNumber.Name, txtNumber);
This will then allow you to call FindName on the StackPanel and find the TextBox.
这将允许您在 StackPanel 上调用 FindName 并找到 TextBox。