我有一个关于c#和Postsharp事件拦截的问题。
我想取消事件的执行,如BeforeDropDown, RowSelected MouseClick与EventInterceptionAspect在postsharp。
但是我找不到一个合适的地方,我可以写代码。例子:
我试过这样做:
[Serializable]
class EventInter : EventInterceptionAspect
{
public override bool CompileTimeValidate(System.Reflection.EventInfo targetEvent)
{
return "FormClosed".Equals(targetEvent.Name);
}
public override void OnInvokeHandler(EventInterceptionArgs args)
{
if condition executes method otherwise no
}
}
的形式:
[EventInter]
public partial class Frm_RomperMesa : KryptonForm
但它没有工作。所以我想知道是否有可能实现我想要的。
提前感谢。
是的,这是可能的。问题是,您试图将事件拦截方面应用于在另一个程序集中定义的事件,而您无法在代码中执行。你甚至不能重写事件,因为它被设置为在
后面的设计器代码中使用基本表单类型来处理this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
必须修改程序集才能完成此操作。使用以下方面和链接来修改
public class EventAspectProvider : TypeLevelAspect , IAspectProvider
{
public IEnumerable<AspectInstance> ProvideAspects(object targetElement)
{
Type t = (Type)targetElement;
EventInfo e = t.GetEvents().First(c => c.Name.Equals("FormClosing"));
return new List<AspectInstance>() { new AspectInstance(e, new EventInter()) };
}
}
[Serializable]
public class EventInter : EventInterceptionAspect
{
public override void OnInvokeHandler(EventInterceptionArgs args)
{
int x = 0;
if (x > 0) //Do you logic here
{
args.ProceedInvokeHandler();
}
}
}
- http://programmersunlimited.wordpress.com/2011/07/27/applying-aspects-to-3rd-party-assemblies-using-postsharp/
- http://programmersunlimited.wordpress.com/2011/08/16/exposing-internal-methods-in-3rd-party-assemblies-for-external-use/
基本上可以归结为修改System.Windows.Forms.dll,我不推荐这样做。但如果是其他第三方供应商的库,那就去用它吧。
一种解决方法是用另一种方法:在方法上使用与事件挂钩的方面,并在满足条件时取消方法的正常执行。这不会阻止事件表单被引发,但它会阻止事件处理代码被执行。
[EventInter]
private void someForm_FormClosed(object sender, EventArg arg) {}
我们在项目中经常使用这种方法。我们有几个方面适用于事件处理方法(异常处理、游标处理等)。
我们更进一步,在程序集级别应用方面,并使用compiletimevalidide来识别事件处理方法的签名。理论上,它不是100%可靠的,但目前为止我们还没有发现这种方法有任何问题。