2012-08-07 60 views
0

现在我会跳过我的代码;用文字描述应该更容易。有没有办法检测Winform TextBox的Leave事件是由Tab还是Shift-Tab或其他事件触发的?

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

  1. 我有一个输入文本框,当用户输入文本不好,我显示错误消息,并且将焦点返回到文本框。
  2. 当用户没有输入任何内容或删除那些内容并离开文本框时,它会执行一些处理,但除此之外的行为会按照Tab键跳转到下一个控件。
  3. 如果我关闭,跳到上一个控件,如果我按下Shift-Tab或关注用鼠标点击的任何东西。
  4. 如果为某些可以自动完成的文本输入一个唯一的前缀,例如可以自动完成为“朝鲜蓟”的“articho”,则代码会自动填充旁边的另一个只读文本框并跳到只读文本框的下一个邻居。 注意:如果我的Shift-Tab具有相同的输入,那么它也会执行相同的操作,但在这种情况下,我希望执行不同的逻辑。
  5. 就像4.但如果我通过点击鼠标离开,然后代码会自动填充文本框 - 很好,但它也会选择我想要的控件。

现在坏了什么是4的秃头部分。;如果我尝试使用Shift-Tab循环所有交互式(而不是标签或禁用的)控件,我不能 - 每4个我的自定义逻辑开始并向前发送焦点。当我在手边的文本框中填写了一些东西时,这只是一个问题,但我仍然想解决这个问题。

有什么想法?有问题吗?

P.S.我不知道如何回答“你有什么尝试?”除了说我使用WinForms好几个月以外,并且我不确定如何在这里继续。谢谢。

+0

Downvoters,请详细说明。 – 2012-08-08 20:39:08

回答

0

也许你可能想尝试TextKeyBox的PreviewKeyDown事件,你可以在其中识别被按下的组合键,并在Shift + Tab键按下时执行不同的逻辑。

+0

谢谢。正如我写的,我不认为这是一个完整的答案。由于我还有一个单独的离开事件,那么我如何让这两个人进行交流?某种形式的共享时间非常快,因为'KeyPreview'会在'Leave'事件之前发生?使事情复杂化,我已经在整个表单上拦截了一个'KeyPreview'事件,并且在Page Up/Page Down上做了一些事情。当他们的关键字不是Page Down/Page Up时,退出该方法不应该花太长时间,但我仍然不确定如何最好地选择时间间隔。此外,关于Timer类使用的任何建议 – 2012-08-08 00:11:52

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

谢谢,我会给这个镜头。我试图尽量减少对'user32.dll'的依赖,所以如果有技术上不需要去那里的方法,我想避免直接调用本地调用。例如,'getCurrentControl()'可以只是'form.ActiveControl';为了获得下一个和之前的标签项,我可以在'container.Controls'后跟一个Linq查询 - 更加昂贵,但是可行。所以,我很好奇 - “user32.dll”的哪些功能我完全需要实现?谢谢。 – 2012-08-08 16:04:56

相关问题