简体   繁体   English

如何通过Tab键及时启用WinForm按钮以获得焦点

[英]How to enable a WinForm button in time to receive focus by tabbing

Visual Studio 2010, C# Visual Studio 2010,C#

I have a ComboBox with a DropDown , AutoComplete set to SuggestAppend and the AutoCompleteSource is from the ListItems . 我有一个带DropDownComboBoxAutoComplete设置为SuggestAppendAutoCompleteSource来自ListItems The user keys data into it until the have the correct entry. 用户将数据键入其中,直到具有正确的条目。 Utill the data matches one of the list items, a button next to the combobox is disabled. 如果数据与列表项之一匹配,则组合框旁边的按钮被禁用。

If the user hits the tab key the autocomplete feature accepts current suggestion. 如果用户点击Tab键,则自动完成功能会接受当前建议。 It also moves on to the next control in tab sequence that is enabled. 它还会移动到启用的选项卡序列中的下一个控件。 Of course since I want it to go to the disbabled button I need to enable it as soon as I validate the entry. 当然,因为我希望它转到disbabled按钮,我需要在验证条目后立即启用它。

The problem is that none of the events I've tried, PreviewKeyDown , LostFocus , SelectedIndexChanged allow me to enable the button in time for it to be proccessed and receive the focus. 问题是我没有尝试过任何事件, PreviewKeyDownLostFocusSelectedIndexChanged允许我及时启用按钮以便进行处理并获得焦点。 It always goes to the next button in tab order which is always enabled. 它始终以Tab键顺序进入下一个按钮,该按钮始终处于启用状态。

I am about ready to leave the button enabled and have it give an error if pressed too soon but I don't want to do it that way. 我准备好让按钮保持启用状态,如果太快按下它就会出错,但我不想这样做。 I also don't want to get into have special mode flags to keep track of when these controls receive focus. 我也不想进入特殊模式标志来跟踪这些控件何时获得焦点。 Validation seems to be a normal thing, but I'm stuck. 验证似乎是正常的事情,但我被困住了。

If the SelectedIndexChanged worked when the user made a match this would be easy. 如果SelectedIndexChanged在用户进行匹配时起作用,则这很容易。 It doesn't fire when the box clears nor when a typed match is found. 当盒子清除时,或者当找到类型匹配时,它不会触发。

You could create your own ComboBox class to encapsulate this behavior. 您可以创建自己的ComboBox类来封装此行为。 Something like this: 像这样的东西:

using System;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            this.myComboBox1.TheButton = this.button1;

            this.myComboBox1.Items.AddRange( new string[] {
                "Monday",
                "Tuesday",
                "Wednesday",
                "Thursday",
                "Friday",
                "Saturday",
                "Sunday"
            } );

            button1.Enabled = false;
        }
    }

    public class MyComboBox : ComboBox
    {
        public Control TheButton { get; set; }

        public MyComboBox()
        {
        }

        bool IsValidItemSelected
        {
            get { return null != this.SelectedItem; }
        }

        protected override void OnValidated( EventArgs e )
        {
            if ( null != TheButton )
            {
                TheButton.Enabled = this.IsValidItemSelected;
                TheButton.Focus();
            }

            base.OnValidated( e );
        }

        protected override void OnTextChanged( EventArgs e )
        {
            if ( null != TheButton )
            {
                TheButton.Enabled = this.IsValidItemSelected;
            }

            base.OnTextChanged( e );
        }
    }
}
try this :

key_press event : key_press事件:

if (e.KeyData == Keys.Enter)
        {
            button2.Enabled = true;
            button2.Focus();
        }

Instead of the event hanlders you mentioned, (LostFocus, SelectedIndexChanged and PreviewKeyDown) use the "Validated" event of your combobox to set the enabled state of the button. 而不是你提到的事件hanlders,(LostFocus,SelectedIndexChanged和PreviewKeyDown)使用组合框的“Validated”事件来设置按钮的启用状态。

You may need to also manually focus on the button to force the focus to move to it though. 您可能还需要手动对焦按钮以强制焦点移动到它。

eg 例如

    private void comboBox1_Validated(object sender, EventArgs e)
    {
        button1.Enabled = true;
        button1.Focus();
    }

With some thought to the other answers here I came up with a partial senario that works without using AutoComplete . 考虑到其他答案,我想出了一个不使用AutoComplete的部分Senario。 A side effect is that the PreviewKeyDown event is called a second time and therefore validation is called twice. 副作用是第二次调用PreviewKeyDown事件,因此调用两次验证。 I wonder why... maybe I should ask another question. 我想知道为什么......也许我应该问另一个问题。

    private void comboBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) {
      if (e.KeyData == Keys.Tab) {
        if (ValidationRoutine()) {
          e.IsInputKey = true;  //If Validated, signals KeyDown to examine this key
        } //Side effect - This event is called twice when IsInputKey is set to true
      }          
    }

    private void comboBox1_KeyDown(object sender, KeyEventArgs e) {
      if (e.KeyData == Keys.Tab) {
          e.SuppressKeyPress = true; //Stops further processing of the TAB key
          btnEdit.Enabled = true;
          btnEdit.Focus();
      }
    }

Once you turn on AutoCompleteMode with any setting other than None , the KeyDown event doesn't fire for Tab anymore the key is silently eaten. 一旦使用除None之外的任何设置打开AutoCompleteModeKeyDown事件就不再为Tab激活,密钥被静默地吃掉。

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

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