All articles| All Pictures| All Softwares| All Video| Go home page| Write articles| Upload pictures

Reading number is top 10 articles
使用ASP.NET,MVC,和LINQ建立一个简单的博客,-,Part,1_[Asp.Net教程]
使用C#开发SmartPhone程序入门_.net资料_编程技术
PHP能得到你是从什么页面过来的,referer的用处_php资料_编程技术
SqlServer2000获取当前日期及格式_[SQL Server教程]
如何实现将Excel表(含多张数据库表)导入数据库(SQLServer)_[SQL,Server教程]
asp.net显示下载提示的下载网页程序_[Asp.Net教程]
Windows XP&2003 IIS安装PHP&MySQL环境完全教程_[PHP教程]
剖析SQL Server 2005查询通知之基础篇_[SQL Server教程]
在DataGrid中为Footer添加自定义内容_[Asp.Net教程]
Visual C++ 6.0教程:Visual C++ 6.0概述
Reading number is top 10 pictures
9.3阅兵全景图6-常规导弹梯队和核导弹梯队
Fierce! China's special forces training the devil2
NeedWallpaper8
A resort photographed beautiful young woman change clothes process vomiting blood1
随便发几张图
美女和狗狗1
Sanya, hainan Haitian party feast promiscuity
Beauty ZhiHuiLin2
擦地板的大叔太好了
美奂绝伦的风景
Download software ranking
Sora aoi, the maid, students' uniforms
星际争霸1.08硬盘免安装版
Unix video tutorial17
仙剑奇侠传98版歌曲
Tram sex maniac 2 (H) rar bag14
仙剑奇侠传98硬盘WINXP版
Unix video tutorial2
Unix video tutorial11
The king of fighters 97(Mobile phone games-apk)
Boxer Classic video1
delv published in(发表于) 2014/1/6 9:10:24 Edit(编辑)
在.NET中利用委托实现窗体间通信_[Asp.Net教程]

在.NET中利用委托实现窗体间通信_[Asp.Net教程]

在.NET中利用委托实现窗体间通信_[Asp.Net教程]

 对于窗体间简单的通信,采用VB6.0的方法就能满足我们的要求,但在一些架构设计复杂的应用中,这种方法就显得有点捉襟见肘了,同时该方法还有一个缺点,就是它仅仅对通过.NET窗体向导添加进去的窗体起作用,而对于自定义的窗体类型我们是无法添加到Forms对象集合中的。而且也和其它诸如构造函数传参等方法一样,会在窗体间大量互相引用各自的成员,造成了彼此之间存在着很大的耦合性,非常不利于窗体模块间的独立,这不符合良好软件设计模式的思想。

  如果我们想在一个窗体中访问另一个窗体中自定义的成员,必须把该成员的可见性设置为Public或者通过属性公开,通过属性公开的话还说得过去,但如果把可见性设置成Public的,这样做就无可避免的破坏了类型封装性的原则,而这一做法也是我们在.NET下开发相当乐意做的,特别是对于初次接触.NET的开发人员,实现访问另一类型中成员的话最先想到的就是把该成员的可见性设置为Public,当然这样做算不上是错误,但把这一做法作为自己的首要灵感,至少从面向对象的角度出发显然是不合适的。

  在.NET下,还为我们提供了另外一种强大的机制来实现窗体通信,这就是委托。委托可理解为一种类型安全的函数指针,.NET下的事件的实现都是以委托做为基础的。关于委托在这篇文章中我就不详细介绍了,后边会有文章专门介绍这一概念。 在此我演示通过在一个窗体里向另外一个窗体里的ListBox控件添加Item项来说明这一方法。因此需要两个窗体,一个MainFrm窗体,一个ChildFrm窗体,另外还需要一个Middle类,作为MainFrm和ChildFrm之间通信的桥梁。我也将给出VB.NET和C#两种语言的代码,以便大家可以做一下比较。

  首先是MainFrm窗体,在MainFrm窗体中,拖一个ListBox控件即可,MainFrm.vb的代码如下(为简单起见,在此省去自动生成的代码):


Public Class Form3

Private Sub Form3_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 AddHandler Middle.SendMessage, AddressOf DoMethod
End Sub

Private Sub DoMethod(ByVal getstr As String)
 Me.ListBox1.Items.Add(getstr)
End Sub
End Class

  再看ChildFrm窗体,在其中拖一个TextBox和一个Button控件,通过在TextBox中输入值后,按Button按钮向MainFrm窗体的ListBox控件中添加Item项。


Public Class Form2

Private Sub Button1_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
 Middle.DoSendMessage(TextBox1.Text)
 TextBox1.Text = ""
 TextBox1.Focus()
End Sub
End Class

  最后看Middle类:


Public Class Middle
 Public Shared Event SendMessage(ByVal str As String)
 Public Shared Sub DoSendMessage(ByVal str As String)
 RaiseEvent SendMessage(str)
End Sub

End Class

  为了更好的演示MainFrm和ChildFrm之间的独立性,修改一下Application.Designer.vb的代码:




Protected Overrides Sub OnCreateMainForm()
 Me.MainForm = Global.WindowsApplication3.MainFrm
 ChildFrm.show()
End Sub

  好了,代码完了,是不是很简单?通过上面的代码可以看出来,通过Middle类,MainFrm和ChildFrm都和Middle类通信,它们之间除了参数的耦合外,已不再引用彼此的内部成员,这样就显得更加独立了。

  下面是对应的C#代码,MainFrm.cs:


public partial class MainFrm: Form
{
 private void MainFrm _Load(object sender, EventArgs e)
 {
  Middle.sendEvent += new Middle.SendMessage(this.DoMethod);
 }
 public void DoMethod(string getstr)
 {
  listBox1.Items.Add(getstr);
 }
}

ChildFrm.cs:

public partial class ChildFrm: Form
{
 public ChildFrm ()
 {
  InitializeComponent();
 }

 private void button1_Click(object sender, EventArgs e)
 {
  Middle.DoSendMessage(this.textBox1.Text);
  textBox1.Text = "";
  textBox1.Focus();
 }
}

Middle.cs:

public static class Middle
{
 public delegate void SendMessage(string str);
 public static event SendMessage sendEvent;
 public static void DoSendMessage(string str)
 {
  sendEvent(str);
 }
}

  同样我们修改一下Program.cs的代码:


static class Program
{
 [STAThread]
 static void Main()
 {
  Application.EnableVisualStyles();
  Application.SetCompatibleTextRenderingDefault(false);
  // Application.Run(new Form1());
  Form1 mainFrm = new Form1();
  childFrm secondFrm = new childFrm();
  secondFrm.Show();
  Application.Run(mainFrm);
 }
}

  比较上面的VB.NET和C#代码,我们可以看出VB.NET允许直接用Event关键字声明事件,而C#则必须由我们自己首先声明事件的委托原型,然后再基于该委托声明事件,从这点看来VB.NET显得更简洁,其实VB.NET编译器在背后会自动的为我们定义一个委托对象,而且该委托与C#代码声明的委托所生成IL代码是一样的,这点大家可以通过Ildasm中间代码查看器来查看一下。引发事件,VB.NET是通过RaiseEvent关键字加上事件名称,而C#则是通过直接使用事件名称;最后是绑定事件的代码,VB.NET是通过AddHandler关键字,C#通过重载的+=操作符,对于以上两点,编译器同样会为我们生成一致的IL代码。

  当然,上面的例子比较简单,不过我们完全可以通过委托实现复杂的窗体通信,比如可以传递复杂的数据类型,同时,可以在设计结构更加良好的中间通信类。但也要提醒大家,不要动不动就要用委托,它会增加程序的复杂性,应该根据自己的需求考虑用何种方法。
作者:liyufeng1983 来源:博客园





添加到del.icio.us 添加到新浪ViVi 添加到百度搜藏 添加到POCO网摘 添加到天天网摘365Key 添加到和讯网摘 添加到天极网摘 添加到黑米书签 添加到QQ书签 添加到雅虎收藏 添加到奇客发现 diigo it 添加到饭否 添加到飞豆订阅 添加到抓虾收藏 添加到鲜果订阅 digg it 貼到funP 添加到有道阅读 Live Favorites 添加到Newsvine 打印本页 用Email发送本页 在Facebook上分享


Disclaimer Privacy Policy About us Site Map

If you have any requirements, please contact webmaster。(如果有什么要求,请联系站长)
Copyright ©2011-
uuhomepage.com, Inc. All rights reserved.