textBox对象的文本更改事件:如何执行文本更改+其他操作
本文关键字:文本 执行 操作 其他 对象 事件 textBox 何执行 | 更新日期: 2023-09-27 18:28:22
我希望当用户键入/更改textBox1
的文本时,同时清除第二个textBox2
的文本。为此,我只需在表单中添加一个事件:
private void textBox1_TextChanged(object sender, EventArgs e)
{
this.textBox2.Text = "";
}
然而,这会导致textBox2
被清除,但用户键入的输入会丢失。实际上:
我的期望:如果textBox1
文本为空,而textBox2
不为空,当用户在第一个文本框中键入"A"时,我将同时清除textBox2
,并在textBox1
中键入字母"A"。
我得到的:textBox2
变清楚了,但字母"A"没有出现在textBox1
中:我必须再打一次才能把它放在正确的位置。
在清除textBox2
的同时,我应该做些什么来保持用户对textBox1
的输入?
编辑:实际上忘记添加代码的一个重要部分,这是我上面发布的方法的"双胞胎"兄弟:
private void textBox2_TextChanged(object sender, EventArgs e)
{
this.textBox1.Text = "";
}
我稍微修正了我的问题:如何在避免textBox2
中的清除被视为text_changed事件的同时满足我的预期行为?
我建议保持处理程序的整洁,而不是做两件事之一:
- 使用
Modified
属性检查用户是否实际修改了文本框。当对Text
进行编程更改时,此bool会自动恢复为false - 改为绑定到键盘事件
使用Modified
以下是如何实现前一个选项:
public void TextBox1_TextChanged(object sender, EventArgs ea)
{
if (textBox1.Modified) textBox2.Clear();
}
这工作得很好,对于任何查看代码的人来说都很容易理解。如果以编程方式更改了Text
属性(在您的情况下,由其他事件处理程序更改),则Modified
属性为false,并且不会进行清除。
额外的好处是,如果您在其他地方进行编程更改,并且确实希望事件处理程序执行,则可以轻松地显式设置Modified = true
:
textBox1.Text = @"I have been set programmatically,
but in this specific case the other box
should still be cleared";
textBox1.Modified = true;
使用键盘事件
以下是如何使用键盘事件实现这一点:
private void TextBox1_TextChanged(object sender, EventArgs e)
{
textBox2.Clear();
}
以及在哪里执行事件处理程序到事件绑定:
textBox1.KeyDown += TextBox1_TextChanged;
textBox1.Paste += TextBox1_TextChanged;
其他改进
通过添加一个将文本框清除逻辑绑定到任何其他文本框的方法,可以使其更通用。以下是我如何在我的测试winforms项目中使用它:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
ClearOnUserInput(textBox1, textBox2);
ClearOnUserInput(textBox2, textBox1);
}
private void ClearOnUserInput(TextBox inputBox, TextBox target)
{
inputBox.TextChanged += delegate {
if(inputBox.Modified) target.Clear();
};
}
}
请注意,我添加了一个单独的方法来附加清除逻辑以保持干燥,并且我还在这里使用匿名委托来避免添加额外的方法。您可以像以前一样轻松地使用两个处理程序。
您可以禁用事件处理程序以避免一个事件干扰另一个事件
你也可以使用全局布尔变量,但我更喜欢这种方法,因为它不需要全局和ifs-
private void textBox1_TextChanged(object sender, EventArgs e)
{
this.textBox2.TextChanged -= textBox2_TextChanged;
this.textBox2.Text = "";
this.textBox2.TextChanged += textBox2_TextChanged;
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
this.textBox1.TextChanged -= textBox1_TextChanged;
this.textBox1.Text = "";
this.textBox1.TextChanged += textBox1_TextChanged;
}
在textBox1
的TextChanged
事件中更改textBox2
的文本时,会触发textBox2
的TextChanged
事件,进而将textBox1
文本设置为""
。
为了解决这个问题,您可以在更改文本之前删除每个处理程序中相反的TextChanged
处理程序,然后将其放回:
private void textBox1_TextChanged(object sender, EventArgs e)
{
this.textBox2.TextChanged -= textBox2_TextChanged;
this.textBox2.Text = "";
this.textBox2.TextChanged += textBox2_TextChanged;
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
this.textBox1.TextChanged -= textBox1_TextChanged;
this.textBox1.Text = "";
this.textBox1.TextChanged += textBox1_TextChanged;
}
您使用的是Text Changed
事件,因此考虑在文本框中有一个字符:
private void textBox1_TextChanged(object sender, EventArgs e)
{
if (textBox1.Text.Length == 1 && textBox2.Text != String.Empty)
textBox2.Text = String.Empty;
}
我建议您在您的场景中使用Key Down
事件。它会在更改文本框的Text
之前启动,并且会在正确的时间检查您的条件。
如果您试图只允许一个文本框接受输入,并始终清除另一个,则可以跟踪代码是否在单独的变量中更改文本。
示例:
// This variable tracks whether or not our code is changing the text
// If it's set to false, then the user is changing the text
private bool ignoreTextChange = false;
private void textBox1_TextChanged(object sender, EventArgs e)
{
if (ignoreTextChange)
{
// Our code is changing the text, so just reset the variable
ignoreTextChange = false;
}
else
{
// Our code is going to change the other text box,
// so set our variable and clear the other text box
ignoreTextChange = true;
this.textBox2.Text = "";
}
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
if (ignoreTextChange)
{
ignoreTextChange = false;
}
else
{
ignoreTextChange = true;
this.textBox1.Text = "";
}
}