[英]Winforms - Invoke Click() event for hidden button
我创建了一个动态创建的表单菜单,并在单击父项后显示/隐藏子项。 我有一个代码可以检查BaseMenuForm
上的键盘键。 当检测到快捷方式时,我需要为相关按钮执行单击事件。 我的问题是当子项不可见时PerformClick()
事件不起作用。
我通过将事件分配给ShortcutAction
属性找到了解决方法。 我认为没有必要两次分配相同的事件,但目前我不知道如何克服这个问题。 我不想显示快捷方式的所有菜单项。
如果配置了快捷方式,您可以看到“TODO”备注和执行解决方法的第二个构造函数。 当用户单击按钮时, Click
事件按预期工作,因此它不能以编程方式工作。
这是我的代码的一部分(仅相关部分):
在设计器上设置了以下属性。 BaseMenuForm_KeyDown
事件按预期调用。
BaseMenuForm.KeyPreview = true;
我的项目 class:
/// <summary>
/// The menu item settings.
/// </summary>
public class MyItem : Button
{
#region Properties
/// <summary>
/// The keyboard keys shortcut.
/// </summary>
public Shortcut Shortcut { get; }
/// <summary>
/// The action that will be called by the shortcut.
/// TODO: why not working when I call PerformClick()
/// </summary>
public Action ShortcutAction { get; set; }
#endregion
#region Constructors
/// <summary>
/// Initializes the item instance.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="text">The text.</param>
/// <param name="onClickEvent">The event that will be triggered on cick.</param>
public MyItem(string name, string text, EventHandler onClickEvent) : this(name, text)
{
if (onClickEvent == null)
{
throw new ArgumentNullException(nameof(onClickEvent));
}
else
{
Click += onClickEvent;
}
}
/// <summary>
/// Initializes the item instance.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="text">The text.</param>
/// <param name="onClickEvent">The event that will be triggered on cick.</param>
/// <param name="shortcut">The keyboard shortcut.</param>
public MyItem(string name, string text, EventHandler onClickEvent, Shortcut shortcut) : this(name, text, onClickEvent)
{
ShortcutAction = () => onClickEvent(this, EventArgs.Empty); //TODO: Why do I need this?
Shortcut = shortcut;
}
#endregion
#region Methods
}
BaseMenuForm:这个 class 包含表单,每个继承这个表单的表单都会有一个菜单。
#region Shortcut
private void BaseMenuForm_KeyDown(object sender, KeyEventArgs e)
{
CheckShortcut(e.KeyData);
}
/// <summary>
/// Checks if the pressed keys is a shortcut combination.
/// </summary>
/// <param name="keyData">The keys.</param>
private void CheckShortcut(Keys keyData)
{
var shortut = (Shortcut)keyData;
Logger.LogDebug($"Got shortcut {shortut}");
if(Shortcuts.TryGetValue(shortut, out var button) && button.ShortcutAction != null)
{
button.ShortcutAction();
//button.PerformClick(); //TODO: why not working !
}
else
{
Logger.LogDebug("No click");
}
}
#endregion
当您按下该键时,您的一个按钮将成为焦点。 它阻止父控件 (BaseMenuForm) 处理此事件。
使固定:
BaseMenuForm.KeyPreview = true;
我将回答以下问题:
PerfromClick
不适用于不可见的按钮? 对 1 的回答- 如果您查看PerfromClick 方法的源代码,您会看到第一条语句是一个检查: if (CanSelect)
并且如果进一步遵循代码,您会看到CanSelect
方法在控件未启用时返回 false 或不可见。 所以这就是原因。
对 2 的回答- 作为一种解决方法,您可以使用按钮的可访问 object 并调用基本上执行单击按钮的默认操作:
button1.AccessibilityObject.DoDefaultAction();
或者作为另一种解决方法,使用反射来调用 OnClick 方法:
button1.GetType().GetMethod("OnClick",
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance)
.Invoke(button, new object[] { EventArgs.Empty });
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.