----- 委托是什么------

其实委托事件很好理解,就当成是c语言中的函数指针或者是回调函数,或者说换种理解方式,信号和槽?触发器和接收器?总之就是一个地方调用了这个函数,那么在另一个地方也会调起《同参数》《同类型》的这么个函数。就目前我学到的,这个就比较接近于信号和槽的关系。

另外由于C#相对自由的类外调用方式,一开始整个代码我看的云里雾里的,但是这两天嗯造看下来,已经大致明白了不少。

比如我们现在做的这个工具,在LBD.IEngTeachV53项目下的ClsTools.cs类中,我们做了两个工具一个叫Intercom,师生对讲,另一个叫Broadcast 视频广播。然后两个工具是这样的,都是先开启教师端,然后再开启学生端。向学生端启动的时候传入教师端的tcp ip 和 tcp port,然后将教师端再将需要的参数补给学生端即可。这只是说个前提,但是不管怎么说,我们只用管一点就是如何在教师端和软件之间互相传递参数。

反正是在本地,那就用WinMessage来传递信号。

包含两个部分:

1.教师端接收exe发送的消息

2.exe接收教师端发送的消息

详解:

需要注意的是,这个ClsTools类中有一个专门用来处理本地WinMessage消息的类对象,叫clsWinMessage,其中有很多方法:

在这个对象上我犯了很多错误,这里只讲解正确用法。

1.教师端接收exe发送的消息:

1>在启动的时候,需要初始化这个对象,这个类中写了一个方法叫InitWinMessage(),调用它就可以了。

2>需要改写InitWinMessage方法,这个方法中需要包含以下几个要素:1.new一下这个成员,否则可能为null 2.添加一个委托如下:

this.clsWinMessage.MessageReceive += new LBD.Frame.Base.Utils.MessageEventHandler(this.WinMessage_MessageReceive);

this.clsWinMessage.CopyDataMessageReceive += new LBD.Frame.Base.Utils.CopyDataMessageEventHandler(this.WinMessage_CopyDataMessageReceive);

这就是添加了一个委托,当clsWinMessage接到消息MessageReceive和CopyDataMessageReceive,分别会触发ClsTools.cs中的WinMessage_MessageReceive和WinMessage_CopyDataMessageReceive方法,并向其中传值。

注意一点就是这个MessageReceive和CopyDataMessageReceive不同,具体哪里不同我不知道,但是在我现在的这个Qt中的SendMessage的方法,发送的其实是CopyData,和单纯的Message好像又有些不一样,具体的区别我不太了解,之后有机会看下MFC可能就懂了。

3>添加消息接收。这个clsWinMessage类并不是什么WinMessage消息都可以接收,只能接受部分被声明的消息码,不然整个程序需要相应的消息码太多了会导致卡顿。由上我们可以想到,Message和CopyData并不是一回事,所以添加的消息也不是按照它原本的方式添加的。

this.clsWinMessage.AddMessage(WM_TAKECLASS);

//上为旧代码,下为新代码

this.clsWinMessage.AddCopyDataMessage(tINTERCOMSTART);

this.clsWinMessage.AddCopyDataMessage(tNEWSELECTED);

而教师端接收WinMessage消息,也只能放在这个WinMessage_CopyDataMessageReceive的方法去接受处理,不在Message中去处理

   private void WinMessage_CopyDataMessageReceive(System.Object sender, CopyDataMessage m)
{
try
{
System.String strData = System.String.Empty;
System.String strClientOpenIntercom = System.String.Empty; if (m.Message == tINTERCOMSTART)
{ strData = m.Data; System.Diagnostics.Trace.WriteLine("InterCome.StartMsg:" + strData); blnIntercomState = true; intIntercomHwnd = int.Parse(strData); }else if(m.Message == tNEWSELECTED)
{
strData = m.Data; string[] SelectedSeatArray = strData.Split('|');
strClientOpenIntercom = "PT_Frame_OpenIntercom"; foreach(string str in SelectedSeatArray)
{
//将消息发送给每一个Actived目录中的成员即可
this.SendToClientMessage(this,0, strClientOpenIntercom);
System.Diagnostics.Trace.WriteLine("SelectedSeatArray:"+str);
} } } catch (System.Exception err)
{
WriteErrorMessage("WinMessage_CopyDataMessageReceive:" + err.Message);
}
}

4>接收消息的句柄

即使注意到上述的问题所在,但是仍有个问题,那就是传入的句柄。需要注意的是这个clsWinMessage类是完全独立的,也就是说它接收消息码其实是有一个自己的隐形窗体在进行,而不是通过整个软件的母窗体来进行,这也是我们需要注意的一点,这个一开始我没注意到

this.InitWinMessage();

if (this.clsWinMessage != null)
{
intHandle = this.clsWinMessage.WinHandle;
}

可以看上述代码,每次启动这个软件的时候就会Init一个 winmessage,当我们关闭的时候也应该要将其Dispose掉(暂时没做,之后会考虑),也就是说每次启动关闭软件的时候,传入的句柄都是可能不同的,和当前的母窗体并没有什么大关系。

2.exe接收框架端的消息

到这里了其实就简单了,向软件发送消息,其实就是直接调用WMUser的SendCopyDataMessage方法直接发送就可以了,不需要别的,就是在这里其实不需要额外声明编码格式,之前我声明的是unicode,但是这样传过来的参数反而是乱码了,是真的傻逼。

关于如何将座位更新

现在我们假设我们可以在主框架中将所有的学生座位信息打包好,然后在软件中也提供了根据用户座位信息刷新的接口---

那么这个时候问题来了,我们怎么知道用户的状态更新?

这时候就要用到委托:

Seats.ValueChanged += new Seats.ValueChangedEventHandler(this.SeatValueChanged);

在这个软件启动的时候添加这个委托,当Seats中的委托ValueChanged触发的时候,触发当前类下的函数SeatValueChanged,并在这个函数中组装所有的座次信息,将其发送给exe,注:句柄是由软件启动后自己发送给教师端的,所以只有当教师端接收到exe发送过来的消息之后才能感知到框架下学生座位信息变化的效果(不过时间很短就是了)。

关于教师端如何向学生端发送消息

这个和之前的 有点不一样,区别在于要知道委托是从哪来传来的,最开始我以为就和WinMessage和 座位的ValueChanged这样的委托消息一样,声明一下就好了,这还是源自对委托的认识不足。而事实上,WinMessage来自WMUser,而ValueChanged来自Seats,但是我自己定义的这个SendToClientMessage呢?并不是某个类延伸出来的方法,只是单独的声明了,这就不对了,这样只能让外部来调用这个ClsTools的委托,而不是从某个类中延伸出来的委托,这就是问题所在。

所以我根据一个向所有学生群发的方法出发,向上去寻找:

这时候才发现,其实我们应该调用的方法,原来是ClsEnTeaching中的Tool_SendMessageToClient方法,而这个所谓的SendToClientMessage方法,其实也就是调用了CallMethod

这样真相大白,其实我们需要的就是clsTools中的SendMessageToClient其实能委托ClsEnTeaching中的Tool_SendMessageToClient方法,并通过其调用NetInterop类,来向学生端发送信号,而不是从某个对象中衍生出一个方法或者对象。

所以我在初始化整个工具类InitTools()处添加了一行

this.clsTools.SendToClientMessage += new ClsTools.SendToClientMessageEventHandler(this.Tool_SendMessageToClient);

这样就可以让我们在clsTools中调用方法的信号发到ClsEnTeaching中,并通过NetInterop发送给学生端,而不是信号无端消失。

C#关于委托的一些事,开发日志的更多相关文章

  1. .NET Core开发日志——RequestDelegate

    本文主要是对.NET Core开发日志--Middleware的补遗,但是会从看起来平平无奇的RequestDelegate开始叙述,所以以其作为标题,也是合情合理. RequestDelegate是 ...

  2. 《Invert》开发日志05:终止

    今天终于看了久闻大名的<独立游戏大电影>,然后我就做了一个坑爹的决定:终止“Invert”项目的开发.没错,在还没正式开工之前,我就决定停掉这个项目,而且是永久终止.做这个决定并不是因为觉 ...

  3. [课程设计]任务进度条&开发日志目录

    任务进度条&开发日志目录 周期 时间 任务 Sprint One   11.14     ●  Scrum团队分工及明确任务1.0    Sprint One   11.15   ●  Scr ...

  4. NET-SNMP开发——日志输出

    NET-SNMP开发——日志输出 net-snmp的日志输出功能是很强大的,与日志输出相关函数声明在net-snmp-5.7.3\include\net-snmp\library\snmp_loggi ...

  5. 仿酷狗音乐播放器开发日志十九——CTreeNodeUI的bug修复二(附源码)

    转载请说明原出处,谢谢 今天本来打算把仿酷狗播放列表的子控件拖动插入功能做一下,但是仔细使用播放列表控件时发现了几个逻辑错误,由于我的播放 列表控件是基于CTreeViewUI和CTreeNodeUI ...

  6. .NET Core开发日志——Entity Framework与PostgreSQL

    Entity Framework在.NET Core中被命名为Entity Framework Core.虽然一般会用于对SQL Server数据库进行数据操作,但其实它还支持其它数据库,这里就以Po ...

  7. Chino 操作系统开发日志 (1) - 为 IoT 而生

    引言 很多人都听说过 IoT (物联网)这个词,越来越多的人在装修时开始选择智能家居,很多人也购买智能音箱做智能家居控制,想必未来一定是 AI + 物联网的时代. 一种技术要发展并走向成熟必须要降低门 ...

  8. C#实现多级子目录Zip压缩解压实例 NET4.6下的UTC时间转换 [译]ASP.NET Core Web API 中使用Oracle数据库和Dapper看这篇就够了 asp.Net Core免费开源分布式异常日志收集框架Exceptionless安装配置以及简单使用图文教程 asp.net core异步进行新增操作并且需要判断某些字段是否重复的三种解决方案 .NET Core开发日志

    C#实现多级子目录Zip压缩解压实例 参考 https://blog.csdn.net/lki_suidongdong/article/details/20942977 重点: 实现多级子目录的压缩, ...

  9. [原创][开源] SunnyUI.Net 开发日志:ListBox 增加跟随鼠标滑过高亮

    QQ群里,寸目说,ListBox鼠标移动时,当前行需要焦点,我想了想,不难实现啊 不就是在鼠标移动时重绘Item嘛,何况选中的Item已经改了颜色了. 见UIListBox代码: protected ...

  10. U-Learning 后端开发日志(建设中...)

    目录 U-Learning--基于泛在学习的教学系统 项目背景 技术栈 框架 中间件 插件 里程碑 CentOS 7搭建JAVA开发环境 接口参数校验(不使用hibernate-validator,规 ...

随机推荐

  1. CentOS系统一键部署jdk,maven,tomcat,mysql

    #!/bin/bash ####使用方法############### # chmod a+x JdTomK-Auto.sh # source JdTomK-Auto.sh ############# ...

  2. JS 模块化- 05 ES Module & 4 大规范总结

    1 ES Module 规范 ES Module 是目前使用较多的模块化规范,在 Vue.React 中大量使用,大家应该非常熟悉.TypeScript 中的模块化与 ES 类似. 1.1 导出模块 ...

  3. [题解] HDU 5115 Dire Wolf 区间DP

    考虑先枚举所有的物品中最后拿走的,这样就分成了2个子问题,即先拿完左边的,再拿完右边的,最后拿选出的那个.令dp(i,j)表示拿完[i,j]所有物品的最小代价.你可能会说,我们拿[i,j]这一段物品的 ...

  4. P4047 [JSOI2010]部落划分 方法记录

    原题链接 [JSOI2010]部落划分 题目描述 聪聪研究发现,荒岛野人总是过着群居的生活,但是,并不是整个荒岛上的所有野人都属于同一个部落,野人们总是拉帮结派形成属于自己的部落,不同的部落之间则经常 ...

  5. day48-JDBC和连接池04-2

    JDBC和连接池04-2 10.数据库连接池 10.5Apache-DBUtils 10.5.1resultSet问题 先分析一个问题 在之前的程序中,执行sql语句后返回的结果集存在如下问题: 关闭 ...

  6. element-ui select可搜索下拉框无法在IOS或Ipad调起小键盘输入法

    参考:https://segmentfault.com/q/1010000021748033 原因:常规select是可以调起小键盘的.但是element-ui的select其实是input.并且这个 ...

  7. 齐博x1小程序集群一个重要功能升级,可以根据圈子会员组显示不同的菜单。

    如下图所示,虽然之前圈子小程序可以自定义会员中心菜单,但是存在一个问题,就是所有会员,比如圈主与普通会员的菜单都将是一样的. 现在升级后,就可以设置不同的圈子会员组,拥有不同的菜单. 比如一个商家,店 ...

  8. Linux文件属性与管理

    文件或目录属性主要包括: 索引节点,inode 文件类型 文件权限 硬链接个数 归属的用户和用户组 最新修改时间 查看命令 ls -lhi /opt 图解: Inode索引节点号,(人的身份证,家庭地 ...

  9. .NET 零开销抽象指南

    背景 2008 年前后的 Midori 项目试图构建一个以 .NET 为用户态基础的操作系统,在这个项目中有很多让 CLR 以及 C# 的类型系统向着适合系统编程的方向改进的探索,虽然项目最终没有面世 ...

  10. iphoneApp Fidder设置

    使用iphone 打开fidder 按照如上配置 安装完毕 然后访问计算机地址- 比如我的计算机ip地址是 192.168.2.10那么我需要在我的safari浏览器中输入192.168.2.10:8 ...