【发布时间】:2010-10-21 21:10:43
【问题描述】:
如果actions 是一个面板,我可以引发它的父级的Click 事件吗?
我目前有这段代码,但Click 事件不是方法,所以这段代码无效。
有谁知道我如何做到这一点?
actions.Click += delegate(object Sender, EventArgs e)
{
((Panel)Sender).Parent.Click();
}
【问题讨论】:
如果actions 是一个面板,我可以引发它的父级的Click 事件吗?
我目前有这段代码,但Click 事件不是方法,所以这段代码无效。
有谁知道我如何做到这一点?
actions.Click += delegate(object Sender, EventArgs e)
{
((Panel)Sender).Parent.Click();
}
【问题讨论】:
不可能直接从另一个 class 引发 C# event(即使它是 public)。您可以提供一个方法(具有足够的访问修饰符)代表您引发event,并在另一个class 中调用该方法。
顺便说一句,这可以通过反射实现,但我认为这是一个肮脏的黑客攻击。
【讨论】:
CLR 中引发事件的大多数类型都有一个受保护的 On[EventName] 方法,该方法负责引发事件。您可以使用反射“从外部”调用这个受保护的方法:
Control parent = ((Control)sender).Parent;
Type parentType = parent.GetType();
MethodInfo onClickMethod = parentType.GetMethod("OnClick", BindingFlags.Instance | BindingFlags.NonPublic);
onClickMethod.Invoke(parent, new object[] { e });
【讨论】:
我能想到的要引发 Click 事件的唯一原因是,如果您正在模拟用户输入。您是否正在开发自动测试驱动程序或类似的东西?如果是这样,可能有比使用仅测试辅助方法玷污代码更好的解决方案。 This google 第一,不知道好不好。
如果您试图在应用程序本身中将其作为一种流控制,我会退后一步,看看这是否是正确的做法——它有点“闻起来很糟糕”。
【讨论】:
我使用反射和扩展方法实现了这一点,因此我可以通过调用(在这种情况下)调用 LinkLabel 点击事件:
var link = new LinkLabel()'
link.Text = "Some link";
link.click();
click() 方法是 C# 扩展方法:
public static void click(this LinkLabel linkLabel)
{
var e = new LinkLabelLinkClickedEventArgs((LinkLabel.Link)(linkLabel.prop("FocusLink")));
linkLabel.invoke("OnLinkClicked", e);
}
它使用另一种扩展方法来:
【讨论】: