我有一个简单的TextBox
,它在开头是空的。我有一个简单的事件_TextChanged,以了解用户何时更改了TextBox
中的任何内容。但是,如果我在代码中自己做任何事情,事件就会触发。比如设置textbox.Text = "Test";
或类似。
private void textNazwa_TextChanged(object sender, EventArgs e) {
changesToClient = true;
}
如何使事件仅触发用户交互而不是代码更改?
答案 0 :(得分:30)
我一直在使用这个过程,它似乎运作良好。如果事件触发并且焦点不在文本框中,则忽略该请求,因此当我设置文本时焦点位于其他位置,但是当用户在文本框中键入时,它具有焦点,因此我确认更改。
private void textNazwa_TextCanged(object sender, EventArgs e)
{
if ( !textNazwa.Focused)
return;
}
答案 1 :(得分:19)
事件本身并不区分通过用户输入输入的文本和通过代码更改的文本。您必须自己设置一个标志,告诉您的代码忽略该事件。例如,
private bool ignoreTextChanged;
private void textNazwa_TextCanged(object sender, EventArgs e)
{
if (ignoreTextChanged) return;
}
然后使用它来设置文本而不是仅调用Text = "...";
:
private void SetTextboxText(string text)
{
ignoreTextChanged = true;
textNazwa.Text = text;
ignoreTextChanged = false;
}
根据您对另一个答案的评论来判断,您听起来有很多文本框。在这种情况下,您可以通过以下方式修改函数:
private void SetTextBoxText(TextBox box, string text)
{
ignoreTextChanged = true;
box.Text = text;
ignoreTextChanged = false;
}
然后这样称呼:
SetTextBoxText(textNazwa, "foo");
这将完成与仅执行textNazwa.Text = "foo"
相同的操作,但会设置让您的事件处理程序知道忽略该事件的标志。
答案 2 :(得分:6)
嗯,你无论如何都不能。您可以做的是在进行更改之前删除处理程序,并在进行更改后将其添加回来。
e.g。
textNazwa.TextChanged -= textNazwa_TextChanged;
textbox.Text = "Test";
textNazwa.TextChanged += textNazwa_TextChanged;
如果您的方法与您将文本框的值更改为textNazwa_TextChanged
的范围相同(例如,两者都在表单中),您可以设置一个标记,或者如果它不足以显示您,您可以使用Chain of Responsiblity来确定是否应该调用textNazwa_TextChanged
方法
答案 3 :(得分:2)
我建议您使用具有属性的演示者为TextBox使用Bindings,因此如果您需要更改代码中的值(例如测试),则不要触发事件或更改为UI代码。您唯一需要做的就是在Presenter上设置一个值。
public class Presenter : INotifyPropertyChanged
{
public string MyTextValue { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
/// Create a method here that raises the event that you call from your setters..
}
然后在Windows窗体代码中,您需要将一个bindingSource设置为Presenter,并为您添加一个绑定textBoxes:
修改强>
private BindingSource myPresenterSource ;
this.myPresenterSource = new System.Windows.Forms.BindingSource(this.components);
// Some time later in the
((System.ComponentModel.ISupportInitialize)(this.myPresenterSource )).BeginInit();
// you set the DataSource of your BindingSource
// m_SettingsBindingSource
//
this.myPresenterSource .DataSource = typeof(Presenter );
// and when you create your TextBox you do this :
this.YourTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Text",
this.myPresenterSource, "MyTextValue", true,
System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
然后在InitializeComponent中设置源代码如下:
myPresenterSource.DataSource = new Presenter();
通过查找如何在Windows窗体中实现Movel-View-Presenter(MVP)来检查更多资源。
答案 4 :(得分:0)
对我来说,我会以这种方式实现它
bool wasUserTyping = false;
private void textNazwa_KeyUp(object sender, KeyEventArgs e){
wasUserTyping = true;
}
private void textNazwa_TextChanged(object sender, TextChangedEventArgs e){
if(wasUserTyping){
//Yaaay!! User did type
}
}