有没有办法检测Winform文本框的离开事件是由Tab或Shift-Tab或其他事件触发的
本文关键字:事件 Tab Shift-Tab 其他 离开 检测 Winform 文本 有没有 | 更新日期: 2024-10-30 14:27:33
我现在跳过我的代码;用语言描述应该更容易。
到目前为止,我有以下逻辑在工作:
- 我有一个输入文本框,
- 当用户输入错误文本时,我会显示一条错误消息并将焦点返回到文本框。
- 当用户不输入任何内容或删除其中的内容并离开文本框时,它会执行一些处理,但其他行为会像它一样 - 按 Tab 键顺序跳转到下一个控件。
- 如果我按 Tab 关闭,则在按 Shift-Tab 或将焦点放在我用鼠标单击的任何内容上时跳转到上一个控件。
- 如果我为某些可以自动完成的文本输入唯一的前缀,例如可以自动完成为"artichoke"的"articho",则代码会自动填充旁边的另一个只读文本框,并跳到只读文本框的下一个邻居。注意:如果我使用相同的输入 Shift-Tab,那么它会做同样的事情,但在这种情况下我想执行不同的逻辑。
- 就像 4. 但是如果我通过单击鼠标离开,那么代码确实会自动填充文本框 - 很棒,但它也会选择我想要的控件。
现在被打破的是 4 的秃头部分; 如果我尝试使用 Shift-Tab 向后循环所有交互式(而不是标签或禁用的)控件,我不能 - 我的自定义逻辑每 4. 启动并将焦点向前发送。只有当我手头的文本框中填写了一些东西时,这只是一个问题,但我仍然想修复这个边缘情况。
有什么想法吗?问题?
附言我不知道如何回答"你试过什么?"类型的问题,只能说我使用了WinForms几个月,我不确定如何在这里进行。谢谢。
您可能想尝试文本框的 PreviewKeyDown 事件,您可以在其中识别正在按下的组合键,如果是 Shift + Tab 键按下,则执行不同的逻辑。
这是我的做法。
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;
}
}
}