Mnemonic button fires Click event of a button but it's not firing Leave event of TextBox
我有一个带有几个文本框和一个按钮的Windows窗体。该按钮具有助记键,可以触发(示例
尝试一些技巧..
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | Dim sButtonBy as String Private Sub TextBox1_GotFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox1.GotFocus sButtonBy ="" End Sub Private Sub TextBox1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyDown If e.Alt Then sButtonBy ="KB" End Sub Private Sub TextBox1_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox1.Leave UpdateIt() End Sub Sub UpdateIt() 'codes here End Sub |
已编辑:
1 2 3 4 5 6 7 8 9 10 | Use this sub to handle every button that added dynamically AddHandler Button1.Click, AddressOf Me.Buttons_Click Private Sub Buttons_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) If sButtonBy ="KB" Then updateit() 'codes here End Sub |
我终于找到了使用来自不同地方的代码段的解决方案。我认为在这里写下来很重要,因为我在任何地方都找不到完整的答案。甚至与此问题相关的问题也很难找到。让我解释一下我做了什么:
1)以表格形式覆盖方法ProcessMnemonic。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | protected override bool ProcessMnemonic(char charCode) { // get the mnemonic key of the button that submits the form (accepts the form or performs some action) char mnemonicChar = DesignerHelper.GetMnemonicChar(btnCreate); // check if the button has a mnemonic key and if the mnemonic key pressed corresponds to it if (mnemonicChar != ' ' && charCode == mnemonicChar) { // get the control that is focused. this could be the textbox where the mnemonic key was pressed Control ctrl = DesignerHelper.FindFocusedControl(this); if (ctrl != null) { // fire the necessary event to update the state of the controls. in my case it's leave event. DesignerHelper.FireEvent(ctrl,"Leave", new EventArgs()); } } return base.ProcessMnemonic(charCode); } |
2)我自己的DesignerHelper类中可用的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | public static Control FindFocusedControl(Control control) { var container = control as ContainerControl; while (container != null) { control = container.ActiveControl; container = control as ContainerControl; } return control; } /// <summary> /// Programatically fire an event handler of an object /// </summary> /// <param name="targetObject"></param> /// <param name="eventName"></param> /// <param name="e"></param> public static void FireEvent(Object targetObject, string eventName, EventArgs e) { /* * By convention event handlers are internally called by a protected * method called OnEventName * e.g. * public event TextChanged * is triggered by * protected void OnTextChanged * * If the object didn't create an OnXxxx protected method, * then you're screwed. But your alternative was over override * the method and call it - so you'd be screwed the other way too. */ //Event thrower method name //e.g. OnTextChanged String methodName ="On" + eventName; MethodInfo mi = targetObject.GetType().GetMethod( methodName, BindingFlags.Instance | BindingFlags.NonPublic); if (mi == null) throw new ArgumentException("Cannot find event thrower named" + methodName); mi.Invoke(targetObject, new object[] { e }); } internal static char GetMnemonicChar(Button btn) { if (btn.UseMnemonic && btn.Text.Contains("&")) { return btn.Text.Substring(btn.Text.IndexOf("&") + 1, 1)[0]; } return ' '; } |
您可以使用" LostFocus "事件,而不要使用" Leave " ...