在.NET中利用委托实现窗体间安全通信

在.NET中利用委托实现窗体间安全通信

大家好,又见面了,我是全栈君。


 

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


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


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


首先是MainFrm窗体,在MainFrm窗体中,拖一个ListBox控件即可,MainFrm.cs的代码如下:


下面是对应的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)


  {



    lsMain.Items.Add(getstr);


  }


}


ChildFrm.cs:


public partial class ChildFrm: Form


{



  public ChildFrm ()


  {



    InitializeComponent();


  } 


  private void btnAdd_Click(object sender, EventArgs e)


  {



    Middle.DoSendMessage(this.textBox1.Text);


    txtItem.Text = “”;


    txtItem.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);


    childFrm child = new childFrm();


    child.Show();


    Application.Run(new mainFrm());


  }


}


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


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

转:http://www.isabout.net/article.asp?id=215



本文转自斯克迪亚博客园博客,原文链接:http://www.cnblogs.com/sgsoft/archive/2007/05/23/757726.html,如需转载请自行联系原作者

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/108044.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • SpringBoot——MybatisPlus修改时空字段不修改

    SpringBoot——MybatisPlus修改时空字段不修改SpringBoot——MybatisPlus修改时空字段不修改

  • 职称计算机一个模块1500,职称计算机考试模块如何选择

    职称计算机一个模块1500,职称计算机考试模块如何选择职称计算机考试模块如何选择选择模块的原则:1、熟悉度:选择自己最常用切最熟悉的模块进行学习考试,像WindowsXP、Word2003、Excel2003、PPT2003、Internet应用、网页制作等都是大家较为熟悉的模块。2、相关性:有些模块之间的相关性很近,比如:学了Word之后再去学习PPT及Frontpage就显得非常容易。3、常用性:像Windows98、Word98、E…

  • redis 乐观锁_什么时候用乐观锁

    redis 乐观锁_什么时候用乐观锁文章目录GeospatialHyperloglogBitmapsRedis事务悲观锁和乐观锁JedisSpringboot继承RedisGeospatial存储地理位置的数据结构应用场景朋友的定位,附近的人,打车距离计算Geospatial底层使用的是Zset127.0.0.1:6379> geoadd city 116.23 40.22 beijing 添加一个数据127.0.0.1:6379> geoadd city 121.47 31.23 shanghai 118.77

  • 渗透之——使用reaver傻瓜式破解wifi之利用路由器WPS漏洞

    渗透之——使用reaver傻瓜式破解wifi之利用路由器WPS漏洞跟这篇破解教程一样,网上破解教程多是基于路由器的WPS漏洞破解,但是这样的路由器只占少数。一般wifi是依据WPA/WPA2加密的,因此想要破解一般的wifi,还得破解这个协议,虽然近期这个协议也被破解了,不过也是很不容易的。刚入门破解,不是很熟悉,在网上找各种破解资料,终于破解成功了临近工作室的wifi,沾沾自喜~本文破解wifi针对一些路由器的WPS(Wi-fiprotectedset…

  • 绘图杂记【1】Python、R等绘图

    绘图杂记【1】Python、R等绘图离散分布水平条形图Discretedistributionashorizontalbarchartimportnumpyasnpimportmatplotlib.pyplotaspltcategory_names=[‘Stronglydisagree’,’Disagree’,’Neitheragreenordisagree’,’Agree’,’Stronglyagree’]results={‘Que

  • PHP操作MySQL对表增加一列(一个字段)

    PHP操作MySQL对表增加一列(一个字段)

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号