C#中有关事件的问题(200分)

  • 主题发起人 主题发起人 VeryCoolBoy
  • 开始时间 开始时间
V

VeryCoolBoy

Unregistered / Unconfirmed
GUEST, unregistred user!
C#的委托机制很好,但到了事件那里就整个让我不爽.
假设我有一个FORM,FORM上有n个TextBox,而每个TextBox都有相应的TextChanged,那么,这时我想在每个TextBox在执行完原有的TextChanged之后,再执行一段我的代码,就可以这样写:
private void button1_Click(object sender, System.EventArgs e)
{
TextBox textBox;
for (int i=0;i<=Controls.Count-1;i++)
{
if (Controls is TextBox)
{
textBox = ((TextBox)Controls);
textBox.TextChanged+=new EventHandler(MySelfChanged);
//MySelfChanged为我的那段代码
}
}
}
但是正如上面所说的,这是在"之后"调用,如何转到"之前"呢,也就是说如何让每个TextBox在执行完原有的TextChanged之前,先执行一段我的代码.
注意,这里原有的TextChanged是未知的,也就是说在你做委托的-=之前,你并不知道原来的那个函数名
 
我也找了半天,好像是没有办法,但你可以在InitializeComponent()中先加上自己的函
数不就行了,反正代码都是自己写的,如果需要自己控制执行与否,加个条件判断就行了。
 
问题就是出在这里啊,正如我上面所说的,我并不是不让原有的代码执行,而是要延后原有代码的执行,这个功能是在基类上实现的,也就是说在基类上根本不知道后继类有多少个TextBox,而且对于每个TextBox.TextChaged事件委托的首个EventHandler也是不可知的.
我觉得这个功能对于组件开发或是框架开发相当有用
 
到CSDN上问问看
 
其实我认为c#提供的事件机制是很爽的:)
事件是方法,事件是属性,事件是指针,
我是明白了c#的机制后,再看delphi,才明白了dephi的方式的。
来看你的代码
在InitializeComponent()中
系统已经自动给你指定上时间了,比如
txtName.TextChanged+=new eventhandler(txtName_TextChanged);
你又通过button1_Click,为这个txtName又指定上了一个textChanged事件。
就是说,txtName上的TEXT改变了,将会执行两个方法(txtName_TextChanged,MySelfChanged),
事实上,根据c#的规范,这两个方法谁先谁后,是不能明确确定的。就是说
你所谓的"之后","之前",也是不明确的。
当然,现在看起来,先“+=”上的先执行。(只是,看起来,或者说是绝大多数情况,但MS似乎没给你保证)
如果,我们就默认这种方式,你不防将它们+=的次序掉换一下,试试。
我认为要严格的实现你要求的功能,你需要继承一个textBox类
class MyTextBox:textBox
{
...
public event Eventhandler BeforeTextChenge;
public event Evnethandler AfterTextChenged;
proctected virtual void OnBeforeTextChenge(EventArge e)
{
if(BeforeTextChenge!=null)
{
BeforeTextChenge(this,e);
}
}
proctected virtual void OnAfterTextChenged(EventArge e)
{
if(AfterTextChenged!=null)
{
AfterTextChenged(this,e);
}
}

protected override void OnTextChenged(EventArge e)
{
OnAfterTextChenged(e);
base.OnTextChaned(e);
OnBeforeTextChenge(e);
}
...
}
然后,在你的button1_click中,你可以随意绑上“之前”,“之后的代码”
if (Controls is MyTextBox)
{
textBox = ((MyTextBox)Controls);
textBox.BeforeTextChange+=new EventHandler(MySelfChanged);
//MySelfChanged为我的那段代码
}

我没有加以验证,可能有疏漏。
 
to chinaplate:
我想你误会我的意思啦,我需要的就是并不继承类的做法,之所以要这种应用,主要是用来编写应用程序框架。。。 C#的事件在我看来应该是一个哈希表,所以我觉得应该是先+=的先执行的。。。
为什么要做这么奇怪的应用,举个例说。。
我现在要在基类中定义一种通用的做法:在DATASET对某行记录保存前我想记录一些信息,比如该行信息是谁创建的,创建时间是什么时候,谁修改的,又是什么时候修改的。。
而这些做法我又不想在子类中实现,因为他们代码可以说完全相同,如果能用在基类中做出来何必要浪费时间再去子类中逐个逐个去写呢?但子类中很可能对DATASET保存前事件写了一些代码。。,而且子类中用了多少个DATASET也是未知的。。
于是我们从理论上讲基类中可以这样做,
for (int i=0;i<Controls.count;i++)
{
if (Controls is DataSet)
{
DataSet ds=(DataSet)Controls;
//必须说明,这些代码是我随手写的,不一定正确
在这里,我们取到了DATASET,
那么问题就在这里,如果子类中的这个DATASET有保存前的事件代码,我们就要先想办法保存出来(我曾用UNSAFE的代码实现啦,但这不是更理想的方法),
然后先插入我们的代码,
接下来再恢复执行子类中定义的代码
这样就可以实现了基类中隐式的将部分事份代码插入到了子类中事件代码的头部,
这个功能在写开发框架是是相当重要的
}
}
 
让我再理解一下你的意思。
你所谓的基类,应该是一个祖先窗口,
子类,是从它派生的窗口,子类窗口中有若干个DataSet,并在子类窗口中订阅了DataSet_I的某个事件。
为了完成一些通用的功能(如记录创建人信息等),你要在祖先窗口中也订阅DataSet_I的某个事件。
你想让祖先窗口中的订阅代码先执行,然后在执行子类窗口中的订阅代码。
那这样,你还是最好应该想我上面继承TextBox一样,继承一个DataSet。

我对你下面的描述,还是不理解。
------------------------------------------------
那么问题就在这里,如果子类中的这个DATASET有保存前的事件代码,我们就要先想办法保存出来(我曾用UNSAFE的代码实现啦,但这不是更理想的方法),
然后先插入我们的代码,
接下来再恢复执行子类中定义的代码
这样就可以实现了基类中隐式的将部分事份代码插入到了子类中事件代码的头部,
 
呵呵。。基类不一定是可见类,另外我觉得这个不是继承与否的问题,这是一种应用程序框架的制作方法,在MFC/DELPHI中都用得较多,
我要求的是基类中能控制与规则子类的一些实现,我所需要实现的功能是在基类中能检查并修正子类的事件,像楼顶的贴子代码所示,我要在基类中为子类的任何一个事件的尾部加多一些代码很容易实现,但问题是如何将这些代码提前到子类事件的头部实现?(我们暂称这种方法为事件套接吧)
我不想做继承,因为我想找一种比继承更优越的方法,对于子类事件的套接很可能发生于每一个事件上(在框架设计中这已是一种事实),如果以后我要为基类中加多另一个事件的套接的话,岂不是又要对某个特别的类别派生一个新类后再去改基类?
用UNSAFE方法,我可以用指针直接替换出事件链表(或者说是事件托委的哈希表更适当)的信息,再将我定义的基类代码加到事件链表的表头,就可以实现,但除用UNSAFE方法外,有没有更好的实现呢?
我的QQ:9319795
 
我基本明白你这个意思了,
你不但想实现+=
txtName.TextChanged+=new eventhandler(txtName_TextChanged);
还象实现+=到某个顺序上,比如说
txtName.TextChanded.bindHandlerAtTop(new eventhandler(..));
txtName.TextChanded.bindHandlerAtTail(new eventhandler(..))
[:D] [:D]
看样子,你已经用unsafe code实现了这个方案,佩服。


 
我是初学.只能关注









 
后退
顶部