博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Observer设计模式中-委托事件-应用在消息在窗体上显示
阅读量:6578 次
发布时间:2019-06-24

本文共 2741 字,大约阅读时间需要 9 分钟。

Observer设计模式:监视者模式。在类中的方法中处理的结果或者消息通过事件委托 的方式发送给主窗体。

因为在其它类中直接访问主窗体类,显示内容是不能直接调用控件赋值的,当然也有别的类似查阅控件名,直接赋值的方式,

这种方式似乎不是被提倡的。而观察者模式是常用的方式。

  初学者在刚开始写程序时,往往把很多的方法函数都写在了主窗体类下,很方便的调用主窗体里边的控件,给予赋值,

但代码多了肯定会乱。所以要进阶必须熟悉当前讲的方式。

下边是个简洁的带参数的事件委托的写的代码

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;
}

转载于:https://www.cnblogs.com/zuochanzi/p/6090212.html

你可能感兴趣的文章
C#实现基于ffmpeg加虹软Arcface的人脸识别demo
查看>>
JavaScript BOM
查看>>
Maven之Centos下安装
查看>>
可伸缩系统的架构经验
查看>>
CRM系统主要业务流程思维导图
查看>>
Android之批量加载图片OOM问题解决方案
查看>>
Weekly 7
查看>>
微软职位内部推荐-Software Engineer II
查看>>
python全栈开发 * 33 知识点汇总 * 180718
查看>>
cetus系列~ 继续分析
查看>>
字符串处理 Codeforces Round #297 (Div. 2) B. Pasha and String
查看>>
uva 12714 2013Dhaka F
查看>>
java_hdfs之读写文件
查看>>
2017-2018-1 20155229 《信息安全系统设计基础》第十三周学习总结
查看>>
mysql中查看sql语句的加锁信息
查看>>
Android SDK下载和更新失败的解决方法
查看>>
(转载)IoC模式
查看>>
L Language——SAP HANA学习笔记系列(二)
查看>>
spring事务配置
查看>>
chrome插件
查看>>