拦截和取消WinForms按钮的Click事件 [英] Intercepting and cancelling the Click event of a WinForms Button
问题描述
有没有办法从父控件捕获一个Button的Click事件,如果父控件中的变量为真,则会阻止它发生?
Is there a way to capture the Click event of a Button from the parent Control and prevent it occuring if a variable within the parent Control is true?
例如:
For example:
private void AssignEventOverrides()
{
foreach (Button button in Buttons)
{
// Get the event assigned at design time
var someUnknownEventHandler = GetTheClickHandlerSomehow(button);
// Unsubscribe the unknown event
button.Click -= SomeUnknownEventHandler;
// Assign the intercepting event
button.Click += button_Click;
}
}
private void button_Click(object sender, EventArgs e)
{
if (!preventClick)
{
// Fire the intercepted event that was previously unsubscribed
}
}
希望有比上述例子更好的方法来做到这一点。只是要注意,我没有任何控制分配给内容的按钮的事件。他们在其他地方订阅,我只需要防止他们发生,如果一个变量在消费父控件上是真的。
Hopefully there's a nicer way to do this than the above example. Just to note, I don't have any control over the events assigned to the afforementioned buttons. They're subscribed elsewhere and I just need to prevent them happening if a variable is true on the consuming parent Control.
我的真实场景:
我使用Windows Mobile 6.5(旧版应用程序重写)我创建了一个可以包含N个子控件的面板控件。面板控件允许iPhone样式垂直滚动。我订阅了孩子 Control
的 MouseMove
事件,并设置一个变量 _isScrolling
到 true
。在 MouseUp
事件中,我将 _isScrolling
设置为 false
。
I'm using Windows Mobile 6.5 (legacy application rewrite) I've created a panel control that can contain N number of child controls. The panel control allows for iPhone style vertical scrolling. I subscribe to the MouseMove
event of the child Control
and set a variable _isScrolling
to true
. In the MouseUp
event I set _isScrolling
to false
.
As 点击
发生在 MouseUp
之前,我可以在单击
事件以确保按下按钮时没有发生滚动。所以基本上,如果我的面板滚动发生,我需要防止Click事件(在设计时订阅)触发。
As Click
occurs before MouseUp
I can check within the Click
event to ensure a scroll hadn't occured when the button was pressed. So basically, if a scroll of my panel occurs, I need to prevent the Click event (subscribed at design time) from firing.
推荐答案
p>感谢 Heheraffles答案,这里是我想出的解决方案:
Thanks to Hehewaffles answer, here's the solution I came up with:
/// <summary>
/// Dictionary for holding the controls design time Click EventHandlers.
/// </summary>
private Dictionary<Control, EventHandler> _interceptedClickEventHandlers;
/// <summary>
/// Recursively moves through the child controls assigning events for scrolling and replacing Click events
/// with an interception EventHandler that prevents the Click event occuring if the Panel was scrolled.
/// </summary>
/// <param name="control">The control to handle the events for and whose children to recurse through.</param>
private void RecursivelySubscribeChildEvents(Control control)
{
if (!(control is IPanelItem))
{
return;
}
// Subscribe the events for the scroll handling
control.MouseDown += new MouseEventHandler(UIPanel_MouseDown);
control.MouseMove += new MouseEventHandler(UIPanel_MouseMove);
control.MouseUp += new MouseEventHandler(UIPanel_MouseUp);
// Intercept the click event
FieldInfo eventClickField = typeof(Control).GetField("Click", BindingFlags.NonPublic | BindingFlags.Instance);
if (eventClickField != null)
{
if (_interceptedClickEventHandlers == null)
{
_interceptedClickEventHandlers = new Dictionary<Control, EventHandler>();
}
// Get the original event and store it against the control for actioning later
EventHandler eventClick = (EventHandler)eventClickField.GetValue(control);
_interceptedClickEventHandlers.Add(control, eventClick);
// Unsubscribe the old event and assign the interception event
control.Click -= (EventHandler)eventClick;
control.Click += new EventHandler(UIPanel_ChildClick);
}
// Recurse the event subscription operation
foreach (Control child in control.Controls)
{
RecursivelySubscribeChildEvents(child);
}
}
private void UIPanel_ChildClick(object sender, EventArgs e)
{
EventHandler interceptedHandler = _interceptedClickEventHandlers[(Control)sender];
if (interceptedHandler != null)
{
// Fire the originally subscribed event if the panel is not scrolling
if (!_isScrolling)
{
interceptedHandler(sender, e);
}
}
}
这篇关于拦截和取消WinForms按钮的Click事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!