简体   繁体   English

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

[英]How to determine whether TextChanged was triggered by keyboard in C#?

I have a method我有一个方法

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

where the textbox in question takes a search string from the user and populates a ListBox with the results on every keystroke.有问题的文本框从用户那里获取一个搜索字符串,并在每次击键时用结果填充一个ListBox

Subsequently, when an item is picked from the ListBox , I would like the choice reflected in the same Textbox .随后,当从ListBox选取一个项目时,我希望该选择反映在同一个Textbox However, I don't want to trigger the search mechanism, which would cause the Listbox to forget its selection.但是,我不想触发搜索机制,这会导致Listbox忘记其选择。

How can I determine whether the TextChanged event was triggered by the user (via they keyboard or maybe copy/paste) or by another method using textBoxPilot.Text = "Pilot name";如何确定TextChanged事件是由用户(通过他们的键盘或复制/粘贴)还是由其他使用textBoxPilot.Text = "Pilot name";方法textBoxPilot.Text = "Pilot name"; ? ?

Thanks.谢谢。

bit of a hack, but....有点黑客,但是......

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

A disabled control will not fire a event.禁用的控件不会触发事件。 So two options are either always disable update the text then re-enable or create a derived class wrapper (using this method you could still do data binding)所以有两个选项要么总是禁用更新文本然后重新启用要么创建派生类包装器(使用此方法您仍然可以进行数据绑定)

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

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

If the user selects "Pilot name" from the list, you set the text box to "Pilot name".如果用户从列表中选择“Pilot name”,则将文本框设置为“Pilot name”。 This will cause the list box to select "Pilot name".这将导致列表框选择“飞行员名称”。 So the selection should be kept.所以应该保留选择。 You just have to break the recursion.你只需要打破递归。

In my scenario where user has to type in text to trigger auto-complete and we didn't want a re-trigger when the auto-complete changes the text again, I used the text lengths.在我的场景中,用户必须输入文本以触发自动完成,并且我们不希望在自动完成再次更改文本时重新触发,我使用了文本长度。 This won't work if user copy/pastes and therefore adds more than 1 character at a time with the keyboard.如果用户复制/粘贴并因此使用键盘一次添加 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;
    }

    ...
}

In your scenario, if you always know the values you want to skip, then you could check for them instead:在您的场景中,如果您始终知道要跳过的值,则可以改为检查它们:

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

or

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM