C#中如何判断TextChanged是否是键盘触发的?

发布于 2024-09-17 12:22:08 字数 444 浏览 6 评论 0原文

我有一种方法

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

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

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

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

谢谢。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

偏爱自由 2024-09-24 12:22:13

在我的场景中,用户必须输入文本才能触发自动完成,并且当自动完成再次更改文本时我们不希望重新触发,我使用了文本长度。如果用户复制/粘贴并因此使用键盘一次添加超过 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;
}

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

温馨耳语 2024-09-24 12:22:12

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

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.

征﹌骨岁月お 2024-09-24 12:22:11

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

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

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.
    }
}
人生百味 2024-09-24 12:22:11

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

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

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

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;
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文