1

I have a Windows Forms with a few TextBoxes and a button. The button has a mnemonic key to get fired (example &OK). I'm subscribed to the Leave event of the TextBox in order to make a validation and update the related controls based on the user input (for example, if I change the cost of a product, the rentability proportion is going to be updated). If I click the OK button, everything works OK but if I use the mnemonic key (Alt+O), the Leave event of the TextBox is fired after the Click event of the button. Because of this, my TextBoxes are not updated before the Click event of the button. Any ideas?

Summary of normal behavior: - Update TextBox value and click on OK button --> TextBox fires Leave Event and values are updated. Then, The Click event of the is handled.

Summary of strange behavior: - Update TextBox value and press the shotcut key (Alt+O) for the OK button --> Click Event of the button is fired and then the Leave event of the TextBox is fired.

Thanks in advanced.

4

3 回答 3

1

尝试一些技巧..

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
于 2013-06-17T04:19:07.987 回答
0

我终于找到了一个使用来自不同地方的代码的解决方案。我认为把它写在这里很重要,因为我在任何地方都没有找到完整的答案。即使是与这个问题相关的问题也很难找到。让我解释一下我做了什么:

1)重写Form中的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
             * 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 ' ';
        }
于 2014-01-03T14:13:47.670 回答
0

您可以使用“LostFocus”事件而不是使用“离开”...

于 2013-06-17T04:12:09.430 回答