我有一个带有几个TextBox和一个按钮的Windows窗体。该按钮有一个助记键被触发(例如& OK)。我订阅了TextBox的Leave事件,以便根据用户输入进行验证并更新相关控件(例如,如果我更改产品的成本,可租赁比例将会更新)。如果我单击确定按钮,一切正常,但如果我使用助记键(Alt + O),TextBox的Leave事件将在按钮的Click事件后触发。因此,我的TextBox在按钮的Click事件之前不会更新。有什么想法吗?
正常行为摘要: - 更新TextBox值并单击OK按钮 - > TextBox触发Leave事件和值更新。然后,处理了Click事件。
奇怪行为摘要: - 更新TextBox值并按下拍摄键(Alt + O)以显示OK按钮 - >单击按钮的事件触发,然后触发TextBox的Leave事件。
先谢谢。
答案 0 :(得分: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
答案 1 :(得分:0)
您可以使用“LostFocus”事件而不是使用“离开”......
答案 2 :(得分:0)
我终于找到了一个使用来自不同地方的代码的解决方案。我认为在这里写下来很重要,因为我没有在任何地方找到完整的答案。即使是与此问题相关的问题也很难找到。让我解释一下我做了什么:
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
* 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 ' ';
}