【问题标题】:How to determine whether TextChanged was triggered by keyboard in C#?如何确定TextChanged是否由C#中的键盘触发?
【发布时间】:2010-09-02 20:35:54
【问题描述】:

我有一个方法

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

有问题的文本框从用户那里获取一个搜索字符串,并用每次击键的结果填充ListBox

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

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

谢谢。

【问题讨论】:

    标签: c# events textbox textchanged


    【解决方案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.
        }
    }
    

    【讨论】:

    • 我最终使用了您的答案和 Scott 的答案的组合: private void listBoxPilot_SelectionChanged(object sender, SelectionChangedEventArgs e) { textBoxPilot.IsEnabled = false;成员 selectedPilot = (Member)listBoxPilot.SelectedItem; textBoxPilot.Text = selectedPilot.firstName; textBoxPilot.IsEnabled = true; } private void textBoxPilot_TextChanged(object sender, TextChangedEventArgs e) { if (textBoxPilot.IsEnabled == false) return; [搜索内容] } 这消除了对新全局变量的需要。谢谢你们俩。
    【解决方案2】:

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

    class myClass : TextBox
    {
        public virtual string TextWithoutEvents
        {
            get
            {
    
                return base.Text;
            }
            set
            {
                bool oldState = Enabled;
                Enabled = false;
                base.Text = value;
                Enabled = oldState;
            }
        }
    }
    

    【讨论】:

    • 感谢您的启发。最后,我结合了你的答案和杰罗德的答案;看我对他帖子的回复。
    【解决方案3】:

    如果用户从列表中选择“Pilot name”,您将文本框设置为“Pilot name”。这将导致列表框选择“Pilot name”。所以应该保留选择。你只需要中断递归。

    【讨论】:

    • 没错,但是,在这种情况下是不行的。用户偶尔会使用箭头键点击结果,ListBox 会随时选择每个项目。
    【解决方案4】:

    在我的场景中,用户必须输入文本才能触发自动完成,并且当自动完成再次更改文本时我们不希望重新触发,我使用了文本长度。如果用户复制/粘贴并因此使用键盘一次添加超过 1 个字符,这将不起作用。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多