我有一个Windows窗体与几个文本框和一个button。 该button有一个助记键被触发(例如和确定)。 我订阅了TextBox的Leave事件,以便根据用户input进行validation和更新相关控件(例如,如果我更改了产品的成本,租赁比例将被更新)。 如果我单击确定button,一切正常,但如果我使用助记键(Alt + O),button的Click事件后触发文本框的Leave事件。 正因为如此,我的文本框没有更新的button的Click事件之前。 有任何想法吗?
正常行为摘要: – 更新TextBox值并点击OKbutton – > TextBox触发Leave事件和值被更新。 然后,处理Click事件。
奇怪的行为总结: – 更新TextBox的值,并按下快捷键(Alt + O)的确定button – >点击该button的事件被激发,然后文本框的Leave事件被激发。
先谢谢了。
尝试一些技巧..
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
编辑:
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
您可以使用“LostFocus”事件而不是使用“离开”…
我终于找到了使用来自不同地方的代码的解决方案。 我认为把它写下来很重要,因为我没有在任何地方找到完整的答案。 即使是与这个问题有关的问题也很难找到。 让我解释我做了什么:
1)重写表单中的ProcessMnemonic方法。
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类中可用的方法:
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 * eg * 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 //eg 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 ' '; }