简体   繁体   中英

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.

Subsequently, when an item is picked from the ListBox , I would like the choice reflected in the same Textbox . However, I don't want to trigger the search mechanism, which would cause the Listbox to forget its selection.

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"; ?

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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