首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >助记按钮激发按钮的Click事件,但不激发TextBox的Leave事件

助记按钮激发按钮的Click事件,但不激发TextBox的Leave事件
EN

Stack Overflow用户
提问于 2013-06-17 12:07:40
回答 3查看 378关注 0票数 1

我有一个带有几个TextBoxes和一个按钮的窗体。按钮有一个用于触发的助记键(example &OK)。我订阅了TextBox的Leave事件,以便根据用户输入进行验证和更新相关控件(例如,如果我更改了产品的成本,则将更新可出租比例)。如果我单击OK按钮,一切正常,但是如果我使用助记键(Alt+O),则在按钮的click事件之后触发TextBox的Leave事件。因此,我的TextBoxes在按钮的Click事件之前不会更新。有什么想法吗?

正常行为总结:-更新TextBox值并单击OK按钮--> TextBox fires事件和值被更新。然后,将处理的Click事件。

奇怪行为总结:-更新Click值并按下OK按钮的快捷键(Alt+O) -->触发按钮的TextBox事件,然后触发TextBox的Leave事件。

在进阶时谢谢。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-01-03 22:13:48

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

1)重写表单中的ProcessMnemonic方法。

代码语言:javascript
运行
复制
        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类中可用的方法:

代码语言:javascript
运行
复制
        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 ' ';
        }
票数 0
EN

Stack Overflow用户

发布于 2013-06-17 12:19:08

尝试一些小把戏..。

代码语言:javascript
运行
复制
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

编辑:

代码语言:javascript
运行
复制
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
EN

Stack Overflow用户

发布于 2013-06-17 12:12:09

你可以使用"LostFocus“事件代替"Leave"...

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17140269

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档