Observer设计模式中-委托事件-应用在消息在窗体上显示
2016-11-22 17:35
218 查看
Observer设计模式:监视者模式。在类中的方法中处理的结果或者消息通过事件委托 的方式发送给主窗体。
因为在其它类中直接访问主窗体类,显示内容是不能直接调用控件赋值的,当然也有别的类似查阅控件名,直接赋值的方式,
这种方式似乎不是被提倡的。而观察者模式是常用的方式。
初学者在刚开始写程序时,往往把很多的方法函数都写在了主窗体类下,很方便的调用主窗体里边的控件,给予赋值,
但代码多了肯定会乱。所以要进阶必须熟悉当前讲的方式。
下边是个简洁的带参数的事件委托的写的代码
今天我犯了个比较郁闷现在想想很搞笑的错误
当然我的程序跟这个不同之处,
我在其它类中写好了事件委托,运行到 ResultEvent(resulteventargs); 启动委托事件时候提示未实例化对象。
后来对比了上边的 列子才发现自己的程序没问题,是自己定义了两个对象,第一个定义的对象没有引用事件,第二个定义了对象引用了事件,而程序里边找不到这个这个对象。很明显啊,类的程序是第一个对象启动起来的,当然相应的时候会找第一个对象。而不是第二个。
第一个对象th
ThreadHelp th = new ThreadHelp(path, add);
th.Start(); 启动程序,没有任何事件注册订阅。运行到 Start()里边 ResultEvent(resulteventargs);代码时找不到应该
具有的 th.ResultEvent += ShowMessage; 所以提示 未实例化。
为什么会出现这种情况,由于上边的代码是先写好的,事件是后加的,后加上事件后,我在Form1_Load 注册订阅的事件委托。
private void Form1_Load(object sender, EventArgs e)
{
ThreadHelp threadhelp = new ThreadHelp();
EventHelper eventhelper = new EventHelper();
threadhelp.ResultEvent += ShowMessage;
}
结果就是出现了找不到实例化的原因。
修改代码:在第一个实力化对象中加入th.ResultEvent += ShowMessage; 问题解决
ThreadHelp th = new ThreadHelp(path, add);
th.ResultEvent += ShowMessage;
th.Start();
总结:刚出错时查了觉得示例化了啊,怎么还报错,刚开始也能意识到驴唇不对马嘴,由于对于事件有段时间没用的模糊,对比写的方式。导致花费了些时间。
第二,未找到对象里边的子对象也会被报错未被实力化,就像这次找不到承接这次事件的订阅者的报错。
附贴一个,主窗体下访问控件的简洁写法
if (txbtxt.InvokeRequired)
{
txbtxt.BeginInvoke(new MethodInvoker(delegate { txbtxt.Text = e.Messjsonstr; }));
}
else
{
txbtxt.Text = e.Messjsonstr;
}
因为在其它类中直接访问主窗体类,显示内容是不能直接调用控件赋值的,当然也有别的类似查阅控件名,直接赋值的方式,
这种方式似乎不是被提倡的。而观察者模式是常用的方式。
初学者在刚开始写程序时,往往把很多的方法函数都写在了主窗体类下,很方便的调用主窗体里边的控件,给予赋值,
但代码多了肯定会乱。所以要进阶必须熟悉当前讲的方式。
下边是个简洁的带参数的事件委托的写的代码
using System; using System.Collections.Generic; using System.Text; namespace Delegate { // 热水器 public class Heater { private int temperature; public delegate void BoilHandler(int param); //声明委托 public event BoilHandler BoilEvent; //声明事件 // 烧水 public void BoilWater() { for (int i = 0; i <= 100; i++) { temperature = i; if (temperature > 95) { if (BoilEvent != null) { //如果有对象注册 BoilEvent(temperature); //调用所有注册对象的方法 } } } } } // 警报器 public class Alarm { public void MakeAlert(int param) { Console.WriteLine("Alarm:嘀嘀嘀,水已经 {0} 度了:", param); } } // 显示器 public class Display { public static void ShowMsg(int param) { //静态方法 Console.WriteLine("Display:水快烧开了,当前温度:{0}度。", param); } } class Program { static void Main() { Heater heater = new Heater(); Alarm alarm = new Alarm(); heater.BoilEvent += alarm.MakeAlert; //注册方法 heater.BoilEvent += (new Alarm()).MakeAlert; //给匿名对象注册方法 heater.BoilEvent += Display.ShowMsg; //注册静态方法 heater.BoilWater(); //烧水,会自动调用注册过对象的方法 } } } 输出为: Alarm:嘀嘀嘀,水已经 96 度了: Alarm:嘀嘀嘀,水已经 96 度了: Display:水快烧开了,当前温度:96度。 // 省略...
今天我犯了个比较郁闷现在想想很搞笑的错误
当然我的程序跟这个不同之处,
我在其它类中写好了事件委托,运行到 ResultEvent(resulteventargs); 启动委托事件时候提示未实例化对象。
后来对比了上边的 列子才发现自己的程序没问题,是自己定义了两个对象,第一个定义的对象没有引用事件,第二个定义了对象引用了事件,而程序里边找不到这个这个对象。很明显啊,类的程序是第一个对象启动起来的,当然相应的时候会找第一个对象。而不是第二个。
第一个对象th
ThreadHelp th = new ThreadHelp(path, add);
th.Start(); 启动程序,没有任何事件注册订阅。运行到 Start()里边 ResultEvent(resulteventargs);代码时找不到应该
具有的 th.ResultEvent += ShowMessage; 所以提示 未实例化。
为什么会出现这种情况,由于上边的代码是先写好的,事件是后加的,后加上事件后,我在Form1_Load 注册订阅的事件委托。
private void Form1_Load(object sender, EventArgs e)
{
ThreadHelp threadhelp = new ThreadHelp();
EventHelper eventhelper = new EventHelper();
threadhelp.ResultEvent += ShowMessage;
}
结果就是出现了找不到实例化的原因。
修改代码:在第一个实力化对象中加入th.ResultEvent += ShowMessage; 问题解决
ThreadHelp th = new ThreadHelp(path, add);
th.ResultEvent += ShowMessage;
th.Start();
总结:刚出错时查了觉得示例化了啊,怎么还报错,刚开始也能意识到驴唇不对马嘴,由于对于事件有段时间没用的模糊,对比写的方式。导致花费了些时间。
第二,未找到对象里边的子对象也会被报错未被实力化,就像这次找不到承接这次事件的订阅者的报错。
附贴一个,主窗体下访问控件的简洁写法
if (txbtxt.InvokeRequired)
{
txbtxt.BeginInvoke(new MethodInvoker(delegate { txbtxt.Text = e.Messjsonstr; }));
}
else
{
txbtxt.Text = e.Messjsonstr;
}
相关文章推荐
- 【原创源码】(01):利用事件-委托,实现主-子窗体动态显示,不同菜单栏,不同工具栏。(类似SQL Server 2000 企业管理器)
- 利用事件-委托,实现主-子窗体动态显示,不同菜单栏,不同工具栏。(类似SQL Server 2000 企业管理器)
- 将.net控件的属性或事件显示在“属性”窗体
- 应用框架的设计与实现——.NET平台(7.事件通知服务.委托.异步编程)
- 技术讲座:.NET委托、事件及应用兼谈软件项目开发
- 运用委托事件,在窗体中传递信息
- js应用之事件触发:隐藏和显示按钮
- 使用委托和事件在窗体间传递数据
- 关于C#/.NET中委托和事件的机制和应用的故事(转)
- [VB.NET] 事件的应用:父窗体和子窗体的数据传送
- js显示隐藏效果,其中注意了一个事件的应用
- 委托与事件的应用---翻页控件
- vs2005的form的委托 实现多线程操作richedit控件显示消息
- 用委托(Delegate)来协调窗体中各用户控件之间的消息
- 事件与委托的简单应用
- 子窗体向父窗体传数值(事件委托)
- [C#应用]得到组件事件的委托列表
- c# 用委托和事件实现不同窗体间的通讯(二)
- 委托和事件入门(二)窗体间传值
- C#判断根据消息判断窗体的事件(WINFROM)