有没有办法检测Winform TextBox Leave事件是由Tab或Shift-Tab还是其他事件触发?

时间:2012-08-07 23:27:09

标签: c# winforms .net-4.0 customization

我现在将跳过我的代码;它应该更容易用文字描述。

到目前为止,我有以下逻辑工作:

  1. 我有一个输入文本框,当用户输入错误文本时,我会显示错误消息并将焦点返回到文本框。
  2. 当用户没有输入任何内容或删除其中的内容并离开文本框时,它会进行一些处理,但行为与其一样 - 按Tab顺序跳转到下一个控件。
  3. 如果我关闭了标签,如果我按下Shift-Tab键或者专注于我用鼠标点击的任何内容,则跳转到上一个控件。
  4. 如果我为某些可以自动完成的文本输入一个唯一的前缀,例如“articho”可以自动完成“朝鲜蓟”,则代码会自动填写旁边的另一个只读文本框并跳到只读文本框的下一个邻居。 注意:如果我使用相同的输入进行Shift-Tab,那么它会做同样的事情,但我想在这种情况下执行不同的逻辑。
  5. 就像4.但如果我通过点击鼠标离开,那么代码会自动填充文本框 - 很棒,但它也会选择我想要的控件。
  6. 现在被打破的是 4的光头部分。;如果我尝试使用Shift-Tab将所有交互式(而不是标签或禁用的)控件向后循环,我不能 - 我的每个4的自定义逻辑开始并向前发送焦点。当我手头的文本框中填充了一些东西时,这只是一个问题,但我仍然想修复这个边缘情况。

    有什么想法?有问题吗?

    P.S。我不知道如何回答“你有什么尝试?”问题的类型,除了说我使用WinForms几个月,我不知道如何继续这里。感谢。

2 个答案:

答案 0 :(得分:0)

您可能想尝试使用文本框中的PreviewKeyDown事件来识别正在按下的组合键,如果按Shift + Tab键,则执行不同的逻辑。

答案 1 :(得分:0)

我是这样做的。

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

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

        protected override void OnLoad(EventArgs e) {
            base.OnLoad(e);
            textBox2.LostFocus += new EventHandler(textBox2_LostFocus);
        }

        void textBox2_LostFocus(object sender, EventArgs e) {
            Control newControl = GetCurrentControl();
            Control prevControl = GetPrevControl(textBox2);
            Control nextControl = GetNextControl(textBox2);

            if (newControl.Handle == prevControl.Handle) {
                MessageBox.Show("Case 4");
            }
        }

        [DllImport("user32.dll")]
        static extern IntPtr GetFocus();

        [DllImport("user32.dll")]
        static extern IntPtr GetNextDlgTabItem(IntPtr hDlg, IntPtr hCtl,
           bool bPrevious);

        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr GetWindow(IntPtr hWnd, GetWindow_Cmd uCmd);

        enum GetWindow_Cmd : uint {
            GW_HWNDFIRST = 0,
            GW_HWNDLAST = 1,
            GW_HWNDNEXT = 2,
            GW_HWNDPREV = 3,
            GW_OWNER = 4,
            GW_CHILD = 5,
            GW_ENABLEDPOPUP = 6
        }


        private Control GetCurrentControl() {
            IntPtr hWnd = GetFocus();
            Control control = Control.FromHandle(hWnd);
            return control;
        }

        private Control GetNextControl(Control ctrl) {
            // I know the last parameter looks wierd, but it works
            IntPtr hWnd = GetNextDlgTabItem(ctrl.Parent.Handle, ctrl.Handle, true);

            Control control = Control.FromHandle(hWnd);
            return control;
        }

        private Control GetPrevControl(Control ctrl) {
            // I know the last parameter looks wierd, but it works
            IntPtr hWnd = GetNextDlgTabItem(ctrl.Parent.Handle, ctrl.Handle, false);
            Control control = Control.FromHandle(hWnd);
            return control;
        }
    }
}