C#自定义事件种种.docx

上传人:b****6 文档编号:6818396 上传时间:2023-01-10 格式:DOCX 页数:19 大小:23.38KB
下载 相关 举报
C#自定义事件种种.docx_第1页
第1页 / 共19页
C#自定义事件种种.docx_第2页
第2页 / 共19页
C#自定义事件种种.docx_第3页
第3页 / 共19页
C#自定义事件种种.docx_第4页
第4页 / 共19页
C#自定义事件种种.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

C#自定义事件种种.docx

《C#自定义事件种种.docx》由会员分享,可在线阅读,更多相关《C#自定义事件种种.docx(19页珍藏版)》请在冰豆网上搜索。

C#自定义事件种种.docx

C#自定义事件种种

一、了解C#中的预定义事件处理机制

    在写代码前我们先来熟悉.net框架中和事件有关的类和委托,了解C#中预定义事件的处理。

    EventArgs是包含事件数据的类的基类,用于传递事件的细节。

    EventHandler是一个委托声明如下

         publicdelegatevoidEventHandler(objectsender,EventArgse)

    注意这里的参数,前者是一个对象(其实这里传递的是对象的引用,如果是button1的click事件则sender就是button1),后面是包含事件数据的类的基类。

    下面我们研究一下Button类看看其中的事件声明(使用WinCV工具查看),以Click事件为例。

         publiceventEventHandlerClick;

    这里定义了一个EventHandler类型的事件Click

    前面的内容都是C#在类库中已经为我们定义好了的。

下面我们来看编程时产生的代码。

        privatevoidbutton1_Click(objectsender,System.EventArgse)

        {

            ...

        }

    这是我们和button1_click事件所对应的方法。

注意方法的参数符合委托中的签名(既参数列表)。

那我们怎么把这个方法和事件联系起来呢,请看下面的代码。

        this.button1.Click+=newSystem.EventHandler(this.button1_Click);

    把this.button1_Click方法绑定到this.button1.Click事件。

    下面我们研究一下C#事件处理的工作流程,首先系统会在为我们创建一个在后台监听事件的对象(如果是button1的事件那么监听事件的就是button1),这个对象用来产生事件,如果有某个用户事件发生则产生对应的应用程序事件,然后执行订阅了事件的所有方法。

二、简单的自定义事件

(1)

    首先我们需要定义一个类来监听客户端事件,这里我们监听键盘的输入。

    定义一个委托。

        publicdelegatevoidUserRequest(objectsender,EventArgse);

    前面的object用来传递事件的发生者,后面的EventArgs用来传递事件的细节,现在暂时没什么用处,一会后面的例子中将使用。

    下面定义一个此委托类型类型的事件

        publiceventUserRequestOnUserRequest;

    下面我们来做一个死循环:

这个监听方法要实用化就得使用“线程”

        publicvoidRun()

     {

    boolfinished=false;

    do

    {

    if(Console.ReadLine()=="h")

    {

    OnUserRequest(this,newEventArgs());

    }

    }while(!

finished);

     }

    此代码不断的要求用户输入字符,如果输入的结果是h,则触发OnUserRequest事件,事件的触发者是本身(this),事件细节无(没有传递任何参数的EventArgs实例)。

我们给这个类取名为UserInputMonitor。

   下面我们要做的是定义客户端的类

    首先得实例化UserInputMonitor类

       UserInputMonitormonitor=newUserInputMonitor();

    然后我们定义一个方法。

      privatevoidShowMessage(objectsender,EventArgse)

      {

          Console.WriteLine("HaHa!

!

");

      }

     最后要做的是把这个方法和事件联系起来(订阅事件),我们把它写到库户端类的构造函数里。

    Client(UserInputMonitorm)

     {

      m.OnUserRequest+=newUserInputMonitor.UserRequest(this.ShowMessage);

      //m.OnUserRequest+=newm.UserRequest(this.ShowMessage);

      //注意这种写法是错误的,因为委托是静态的

     }

     下面创建客户端的实例。

       newClient(monitor);

     对了,别忘了让monitor开始监听事件。

        monitor.run();

     大功告成,代码如下:

usingSystem;

classUserInputMonitor

{

publicdelegatevoidUserRequest(objectsender,EventArgse);

//定义委托

publiceventUserRequestOnUserRequest;

//此委托类型类型的事件

publicvoidRun()

{

boolfinished=false;

do

{

if(Console.ReadLine()=="h")

{

OnUserRequest(this,newEventArgs());

}

}while(!

finished);

}

}

publicclassClient

{

publicstaticvoidMain()

{

UserInputMonitormonitor=newUserInputMonitor();

newClient(monitor);

monitor.Run();

}

privatevoidShowMessage(objectsender,EventArgse)

{

Console.WriteLine("HaHa!

!

");

}

Client(UserInputMonitorm)

{

m.OnUserRequest+=newUserInputMonitor.UserRequest(this.ShowMessage);

//m.OnUserRequest+=newm.UserRequest(this.ShowMessage);

//注意这种写法是错误的,因为委托是静态的

}

}

三、进一步研究C#中的预定义事件处理机制

    可能大家发现在C#中有些事件和前面的似乎不太一样。

例如

      privatevoidtextBox1_KeyPress(objectsender,System.Windows.Forms.KeyPressEventArgse)

      {

      }

      this.textBox1.KeyPress+=newSystem.Windows.Forms.KeyPressEventHandler(this.textBox1_KeyPress);

    这里使用了KeyPressEventArgs而不是EventArgs作为参数。

这里使用了KeyEventHandler委托,而不是EventHandler委托。

    KeyPressEventArgs是EventArgs的派生类,而KeyEventHandler的声明如下

      publicdelegatevoidKeyEventHandler(objectsender,KeyEventArgse);

   是参数为KeyEventArgs的委托。

那为什么KeyPress事件要这么做呢,我们可以从两个类的构造函数来找答案。

      publicEventArgs();

      publicKeyPressEventArgs(charkeyChar);

    这里的keyData是什么,是用来传递我们按下了哪个键的,哈。

    我在KeyEventArgs中又发现了属性

       publiccharKeyChar{get;}

    进一步证明了我的理论。

下面我们来做一个类似的例子来帮助理解。

四、简单的自定义事件

(2)

   拿我们上面做的例子来改。

    我们也定义一个EventArgs(类似KeyEventArgs)取名MyEventArgs,定义一个构造函数publicMyEventArgs(charkeyChar),同样我们也设置相应的属性。

代码如下

usingSystem;

classMyMyEventArgs:

EventArgs

{

privatecharkeyChar;

publicMyMyEventArgs(charkeyChar)

{

this.keychar=keychar;

}

publiccharKeyChar

{

get

{

returnkeyChar;

}

}

}

因为现在要监听多个键了,我们得改写监听器的类中的do...while部分。

改写委托,改写客户端传递的参数。

好了最终代码如下,好累

usingSystem;

classMyEventArgs:

EventArgs

{

privatecharkeyChar;

publicMyEventArgs(charkeyChar)

{

this.keyChar=keyChar;

}

publiccharKeyChar

{

get

{

returnkeyChar;

}

}

}

classUserInputMonitor

{

publicdelegatevoidUserRequest(objectsender,MyEventArgse);

//定义委托

publiceventUserRequestOnUserRequest;

//此委托类型类型的事件

publicvoidRun()

{

boolfinished=false;

do

{

stringinputString=Console.ReadLine();

if(inputString!

="")

OnUserRequest(this,newMyEventArgs(inputString[0]));

}while(!

finished);

}

}

publicclassClient

{

publicstaticvoidMain()

{

UserInputMonitormonitor=newUserInputMonitor();

newClient(monitor);

monitor.Run();

}

privatevoidShowMessage(objectsender,MyEventArgse)

{

Console.WriteLine("捕捉到:

{0}",e.KeyChar);

}

Client(UserInputMonitorm)

{

m.OnUserRequest+=newUserInputMonitor.UserRequest(this.ShowMessage);

//m.OnUserRequest+=newm.UserRequest(this.ShowMessage);

//注意这种写法是错误的,因为委托是静态的

}

}

多个控件公用一个事件

private void Form1_Load(object sender, System.EventArgs e) 

  { 

   int a=0; 

   int x=0,y=0; 

   for (a=0;a<=99;a++) 

   { 

   n[a] = new Button(); 

   n[a].BackColor =Color.White; 

   n[a].FlatStyle = FlatStyle.Flat; 

   n[a].Width = panel1.Width / 10; 

   n[a].Left = x * n[a].Width; 

   n[a].Height = panel1.Height / 10; 

   n[a].Top = y * n[a].Height; 

   n[a].Name = "b" + a; 

   panel1.Controls.Add(n[a]); 

   panel1.Controls[a].MouseDown  += new MouseEventHandler(this.ButtonArray_OnClick); 

    

    

  

  

   x += 1; 

   if (x == 10) 

   { 

    x = 0; 

    y += 1; 

   } 

   } 

  

    

  

  } 

  

  private void ButtonArray_OnClick(object sender, MouseEventArgs e) 

  { 

   MouseEventArgs arg=(MouseEventArgs)e; 

       Button b1=(Button)sender; 

   if (arg.Button==MouseButtons.Right ) 

   b1.BackColor=Color.White ; 

   else 

   { 

   //b1.BackColor =Color.White ; 

   b1.Image=Image.FromFile("f:

\\my documents\\my pictures\\elements\\regular_smile.gif"); 

   } 

    

  } 

 } 

 }

C#.NET中动态添加与删除控件 

 

  介绍

  数组为共享公用功能的一组控件一起工作提供了便捷的途径。

例如,一组控件可能用于显示相关的数据,或者在被点击时提供相关的行为。

C#本身并不支持控件数组的建立,但是你可以通过编程复制控件数组的所有功能。

本文介绍复制控件数组功能的简单组件的建立。

控件数组的主要用处有:

1,使用相同的名称与索引访问一组控件,允许用编号检索和设置数据项并且在整个数组中重复。

这个功能可以使用下面的代码实现。

伪代码

myControl[myIndex].MyProperty=myValue;

myControl[myIndex+1].MyMethod

 

2,多个对象使用同一个事件处理程序(eventhandler)处理事件,在这些事件中检索和使用索引,代码如下:

伪代码

privatevoidmyControl_Click(System.Objectsender,System.EventArgse)

  {

     Messagebox.Show("YouhaveclickedMyControlnumber"+

        myControl.Index);

}

3,在运行时动态添加或者删除控件,代码如下:

伪代码

for(inti=1;i<6;i++)

{

  //插入代码来建立控件并给属性赋值

}

 

C#允许你复制与控件数组相关的一些功能。

例如,你能使用委托把多个对象的事件绑定到一个事件处理程序。

但是,如果把这些功能合并到一个动态的、容易管理的组件中更加简便。

本文将建立有下面特性的组件:

  ·建立索引和排序控件的集合。

将使用按钮集合来演示。

  ·一个事件处理程序来处理衍生的按钮的点击事件。

  ·使用索引引用控件和成员的代码。

  ·给窗体动态添加和删除控件的代码。

 

  建立项目

  在本节中将建立并命名一个项目,并给该项目添加一个类。

该类将封装实现控件数组的代码。

  1、选择File->New->Project菜单打开NewProject对话框。

  2、从VisualC#项目列表中选择WindowsApplication项目模版,在Name框中输入ButtonArrayProject。

  3、选择File->SaveAll保存项目。

  实现一个集合

  ButtonArray类会处理通过一个集合的实现来保存和组织控件数组的事务。

集合是包含索引对象变量列表的对象,也包含add、remove等方法和其它的操作对象。

本节中将建立一个继承自System.Collections.CollectionBase(.NET框架组件中提供必要的集合功能的类)的类,并实现提供必要功能的方法。

  建立继承类的过程:

  1、从Project菜单中选择AddClass。

  2、根据情况把类命名为ButtonArray.cs。

类的代码编辑器将打开。

  3、在类的声明中,指定它继承自.NET框架组件的System.Collections.CollectionBase类。

publicclassButtonArray:

System.Collections.CollectionBase

{

  //省略了设计者增加的代码

}

 

  System.Collections.CollectionBase类为集合提供了很多必要的功能。

其中包括一个跟踪集合中对象的List对象,维护集合中当前对象数量的Count属性,允许删除特定位置索引的对象的RemoveAt方法。

在实现控件数组集合时会使用到它们。

  因为每个控件数组与一个窗体关联,索引必须添加一个字段来保存该窗体的引用。

通过建立私有的、只读字段来保存引用,可以保证每个控件数组组件只与以一个窗体关联。

  为组件建立私有、只读字段

  立即给类声明添加下面的代码:

privatereadonlySystem.Windows.Forms.FormHostForm;

 

  在集合中实现的第一个方法是AddNewButton。

该方法建立一个新的按钮控件并把它添加到目标窗体。

你也可以使用该方法为新按钮设置初始属性。

  实现AddNewButton方法

  在ButtonArray类的代码编辑器中输入下面的代码:

publicSystem.Windows.Forms.ButtonAddNewButton()

{

  //为Button类建立新的实例

  System.Windows.Forms.ButtonaButton=new

     System.Windows.Forms.Button();

  //将该按钮添加到集合的内部列表

  this.List.Add(aButton);

  //把控件集合中的按钮添加到被HostForm字段引用的窗体

  HostForm.Controls.Add(aButton);

  //设置该按钮对象的初始属性

  aButton.Top=Count*25;

  aButton.Left=100;

  aButton.Tag=this.Count;

  aButton.Text="Button"+this.Count.ToString();

  returnaButton;

}

 

  上面的方法的功能是:

  1、建立一个新按钮。

  2、把它添加到内部列表和HostForm引用的窗体的控件集合。

  3、设置初始属性,包括设置Tag属性来索引该按钮。

你可以在这一段中添加代码为控件设置更多的属性。

  4、返回新按钮,这样它就能立即被修改并指定给其它的对象引用。

  你必须建立一个构造函数(组件被初始化时运行的方法),当控件数组类的一个新实例被建立时,它用来设置HostForm字段的值并把新按钮添加到窗体。

可以使用下面的方式达到这个目的。

  建立构造函数

  为类建立构造函数。

//使用下面的构造函数代替默认的构造函数

publicButtonArray(System.Windows.Forms.Formhost)

{

  HostForm=host;

  this.AddNewButton();

}

 

  构造函数需要一个参数,即放置按钮数组的窗体。

它把该值指定给HostForm字段,接着类的AddNewButton方法给窗体添加一个新按钮。

  暴露控件数组

  现在已经建立了建立和跟踪数组中控件的途径,但是还必须把它们暴露给开发者。

可以通过属性实现这个功能。

我们将建立一个默认索引器基于特定按钮的索引返回它的引用。

这样你就能编程使用典型控件数组中的MyButtonArray(myIndex)语法了。

建立默认属性

  给组件添加下面的代码:

publicSystem.Windows.Forms.Buttonthis[intIndex]

{

get

  {

     return(System.Windows.Forms.Button)this.List[Index];

  }

}

 

  实现Remove方法  

  现在已经建立了暴露数组中按钮的属性,可以建立从数组中删除按钮的机制了。

为了从数组中删除一个按钮,必须从集合的内部List对象和窗体的Controls集合中删除它。

  给组件添加下面的方法:

publicvoidRemove()

{

  //检查以确保有按钮可以删除

  if(this.Count>0)

  {

     '从主窗体上的控件集合的数组按钮数组中删除最后一个

     '注意在访问数组时使用了默认属性

     HostForm.

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 自然景观

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1