如何确定TextChanged是否是由C#中的键盘触发的?

时间:2010-09-02 20:35:54

标签: c# events textbox textchanged

我有一个方法

private void textBoxPilot_TextChanged(object sender, TextChangedEventArgs e)
{ ... }

其中有问题的文本框从用户处获取搜索字符串,并在每次击键时填充ListBox并显示结果。

随后,当从ListBox中挑选某个项目时,我希望该选项反映在同一个Textbox中。但是,我不想触发搜索机制,这会导致Listbox忘记其选择。

如何确定TextChanged事件是由用户(通过键盘还是复制/粘贴)或使用textBoxPilot.Text = "Pilot name";的其他方法触发的?

感谢。

4 个答案:

答案 0 :(得分:1)

有点黑客,但是......

public class MyForm : Form
{
    private bool _ignoreTextChanged;

    private void listView1_SelectionChanged( object sender, EventArgs e )
    {
       _ingnoreTextChanged = true;
       textBoxPilot.Text = listView1.SelectedValue.ToString(); // or whatever
    }

    private void textBoxPilot_TextChanged( object sender, TextChangedEventArgs e )
    {
       if( _ignoreTextChanged )
       {
           _ignoreTextChanged = false;
           return;
       }

       // Do what you would normally do.
    }
}

答案 1 :(得分:1)

禁用的控件不会触发事件。所以两个选项要么总是禁用更新文本然后重新启用或创建派生类包装器(使用此方法仍然可以进行数据绑定)

class myClass : TextBox
{
    public virtual string TextWithoutEvents
    {
        get
        {

            return base.Text;
        }
        set
        {
            bool oldState = Enabled;
            Enabled = false;
            base.Text = value;
            Enabled = oldState;
        }
    }
}

答案 2 :(得分:0)

如果用户从列表中选择“Pilot name”,则将文本框设置为“Pilot name”。这将使列表框选择“Pilot name”。所以应该保留选择。你只需打破递归。

答案 3 :(得分:0)

在我的情况下,用户必须输入文本以触发自动完成,并且当自动完成再次更改文本时,我们不希望重新触发,因此我使用了文本长度。如果用户复制/粘贴并因此一次在键盘上添加了多个字符,则此操作将无效。

private void HandleTextChanged(object sender, TextChangedEventArgs e){
    var oldText = e.OldTextValue;
    var newText = e.NewTextValue;

    // Assuming text changed from keyboard is always 1 character longer,
    // ignore this text changed event if new text > 1 character longer.
    if (newText.Length > oldText.Length + 1) {
        return;
    }

    ...
}

在您的情况下,如果您始终知道要跳过的值,则可以改为检查它们:

if (newText == "Pilot name") {
    return;
}

if (myListOfNamesToIgnore.Contains(newText)) {
    return;
}