现在开发的一个 vb.net系统,其中有两个窗体:alert窗体和 case窗体。

在alert窗体中列出了当前可以操作的若干个alert(可以理解为数据记录),用户可以选择将其中一个或几个alert加入一个case(可以理解为若干条记录的集合)中。

加入case的这个操作要调用case窗体来完成,由于同时要输入一些相关信息,所以完成时间未知;由于在case窗体中也可能删除某些alert,所以哪些alert最后能够成功加入case也是未知的。

这些alert加入case以后,在alert窗体中要以彩色显示。

上面这个功能,可以使用委托来实现。下面对此进行介绍。

用拟人化的方式来解释:alert窗体,相当于公司的经理,经理手里有若干条工作任务需要完成,但经理自己不会做,只能让公司员工去做;case窗体,相当于公司员工,要去完成经理交代的任务;经理和员工之间,需要有一个沟通的渠道(比如:电话、电报、电邮、小黑板、对讲机,等等),这个渠道既不属于经理,也不属于员工,而是与经理和员工平等的,这个沟通渠道就是委托机制。经理通过这个渠道安排员工去完成某几项工作任务,员工何时能够完成不知道,能够完成几项也不知道,但是员工做完的时候,会返回给经理已经完成的工作清单,经理根据这份工作清单刷新自己手里的任务列表。

下面是相关的代码:

'   在类定义的外面,定义了一个委托,以便在不同的类之间传递信息,这就是沟通渠道

'       具体来说,经理类( frmSuspiciousAlert )调用了 员工类(_frmSuspiciousAlert_case)

'       经理让员工干活(把几笔交易加入到case中),但是什么时候能干完,经理不知道;员工具体添加了哪几笔交易,经理也不知道

'       因此让员工在干完活之后告诉经理一声,并返回所添加的交易的行号

'   这就是这个委托的功能

Public Delegate Sub CallBackManager_saveCase(ByVal rowIDs As List(Of String), ByVal caseID As Integer)    '  委托1,沟通渠道

--------------------------------------------------------------------------------------------------------------------------------------------------------------

Public Class _frmSuspiciousAlert_case     ‘   case窗体,公司员工

Dim myCallBack_saveCase As CallBackManager_saveCase       ' 委托2: 作为员工,要有能够通知经理的基本能力(不论具体方式:打电话,发短信,发电邮...)

'  注意: 有这个能力不代表一定会去做,具体做不做,取决于经理有没有交待员工这样做

'   委托3: 这里是个供经理调用的接口,经理通过这个接口交待员工(注册一个委托,表示干这个活是经理委派的)

Public Sub registerDelegate_saveCase(ByVal _callBack As CallBackManager_saveCase)

myCallBack_saveCase = _callBack

End Sub

'   构造函数,参数为一个 dataTable ,一个 caseID  和 一个可以操作的caseID列表 ; add to case

'        此时的操作是将这个dataTable中的若干笔交易添加到这个已有的Case中;  若_caseID为0 则添加到新的case

Sub New(_dataTable As DataTable, _caseID As Integer, _enabledCaseIDs As List(Of Integer))

InitializeComponent()

enabledCaseIDs = _enabledCaseIDs

lbl_caseID.Text = _caseID.ToString   ' 添加到case

'  注意,由于查看case时 tb_caseID.Text不为0        '  所以,当 tb_caseID.Text = 0 时,表示添加交易到新的case

newDataTable = _dataTable

End Sub

'  员工干活: 当点击此按钮时,把界面上显示的这些case信息保存到数据库中

Private Sub btn_save_Click(sender As Object, e As EventArgs) Handles btn_save.Click

'  准备返回给经理(frmSuspiciousAlert)的字符串列表: 添加成功的各个rowID

Dim listRowID_added As List(Of String) = New List(Of String)

conn.BeginTrans()  '  开始事务处理

If saveDatasOK(listRowID_added) Then  '  如果存盘成功(listRowID_added,完成的工作清单)

conn.CommitTrans()    ' 提交更改

If IsNothing(myCallBack_saveCase) = False Then   '  如果 事先有个委托(这个委托不是空的,表示干这个活是受经理委派的)

myCallBack_saveCase.Invoke(listRowID_added, CInt(lbl_caseID.Text))    '   委托4: 告知经理,活干完了,并且交上一份工作清单;

‘  注意: 如果经理(frmSuspiciousAlert)那里有个公共操作(ddd),这里也可以直接对其操作,  'frmSuspiciousAlert.ddd(listRowID)     ’ 看上去效果似乎差不多;但是其有弊端(只有在知道经理是谁的情况下,才能这样做; 而且这样直接操作其他页面, 也是不安全的,耦合性也很高),所以如果不知道谁是经理(不知道哪个页面调用了本页面),就只能用委托了   所以,尽量不要使用这种方式

' 由于这里有个委托,所以经理(frmSuspiciousAlert)那里会有个操作(刷新界面),此时活动界面(焦点)会转移到经理那边

Me.Focus()    ' 这里重新获取焦点,本界面又成为活动界面

End If

Else   '  如果存盘失败

conn.RollbackTrans()    '  回滚

End If

End Sub

Private Function saveDatasOK(ByRef listRowID_added As List(Of String)) As Boolean

Dim strTableName As String = "  AT2_SSIS_SUS_ALERTS  "

Dim oReturnNonQuery As QueryReturnReader

Dim commitsuccess As Boolean = True

For Each _row As DataGridViewRow In dgv_alerts.Rows    '  对于 dgv 中的每一行(一行就是一个alert)

Dim strCmd As String = "update " & strTableName & " set "    '   所要更新的表

strCmd &= " CASE_ID = " & CInt(lbl_caseID.Text)  '_caseID     '  case ID

Dim rowID As String = _row.Cells("rowid").Value().ToString.Trim

listRowID_added.Add(rowID)    '  完成了一项工作,加入清单中

strCmd &= " where rowid = '" & rowID & "'"       '  所要更新的位置

End Function

End Class

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Public Class frmSuspiciousAlert       ‘  alert窗体,公司经理

'  当鼠标右键点击进入菜单 Add To New Case 时,将当前选中的这几笔交易加入到某个 可疑Case中

Private Sub clickTSM_addToCase(ByVal sender As Object, ByVal e As System.EventArgs) Handles TSMI_AddToCase.Click

Dim _dt As DataTable = getDataTableFromDgv(dtgAML, True)  '   获取当前dgv的选中的那些行组成的 dataTable(所需要完成的工作清单)

'   首先实例化对象(安排一个员工去干活),将这几笔交易加入到 新的(caseID 为 0) 或者 已有的 case 中

Dim frm As _frmSuspiciousAlert_case = New _frmSuspiciousAlert_case(_dt, caseID, dgvCaseIDs)

'   这里加了个委托,当操作成功时(成功将若干笔交易加入case),返回一个信号,以便改变 dgv的显示状态(行的颜色,行头,等等)

'   委托5: 对员工(_frm2)交待(registerDelegate):你干完活要通知经理(CallBackManager),以便经理这里收尾工作(doThingWhenCallBack)

frm.registerDelegate_saveCase(New CallBackManager_saveCase(AddressOf changeDGV_bySaveCaseResults))

frm.Show()   ' 员工干活去了,何时能够干完?不知道

End Sub

‘  当员工干完时,根据员工返回的清单,经理刷新已经完成的工作清单

Private Sub changeDGV_bySaveCaseResults(ByVal listRowID As List(Of String), ByVal caseID As Integer)

'MessageBox.Show("经理我知道了,这些交易已经成功保存到case " & listRowID.Count)

For Each _rowID As String In listRowID

For Each _row As DataGridViewRow In dtgAML.Rows  '   对于 dgv中一些行    ,如果改变了某个交易的case状态,则改变其底色

If _row.Cells("rowid").Value().ToString.Trim = _rowID Then

_row.DefaultCellStyle.BackColor = color_inCase      '  底色变色

_row.HeaderCell.Value = caseID.ToString             '   caseID

_row.ReadOnly = True                        '   只可读

End If

Next

Next

End Sub

End Class

在vb.net中使用委托:经理 和 员工的更多相关文章

  1. [转载]C#中MessageBox.Show用法以及VB.NET中MsgBox用法

    一.C#中MessageBox.Show用法 MessageBox.Show (String) 显示具有指定文本的消息框. 由 .NET Compact Framework 支持. MessageBo ...

  2. VB.NET中图像处理的一些技巧以及其和C#图像处理的差距。

    早期的时候我使用的开发工具是VB6,VB6做图像处理的速度在我的软件Imageshop中有所体现,还是算可以的.目前,我已经改用C#来研究图像算法,C#中有指针,做图像处理起来效率确实要高不少.VB. ...

  3. VB.NET中的除法运算符 与 C#中的除法运算符

    VB.NET中的除法运算符有两个:/(浮点除法).\(整数除法) C#中的除法运算符只有一个:/(除法) VB.NET中的除法运算符与C#中的除法运算符存在很大的差异,使用时注意区分. 关于VB.NE ...

  4. VB6中的引用传递 与 VB.NET中的引用传递的区别

    首先注意一点,在VB6中缺省参数传递的方式是:引用传递,而在VB.NET中缺省参数传递的方式是:值传递. 然后我们看下面VB6中的引用传递与VB.NET中的引用传递的对比. VB6中的引用传递 Pri ...

  5. 2.C#中通过委托Func消除重复代码

    阅读目录   一:重复的代码 二:C#中通过委托Func消除重复代码 一:重复代码    public class Persion { public string Name { get; set; } ...

  6. c++中实现委托

    成员函数指针与高性能的C++委托(上篇) 撰文:Don Clugston 引子 标准C++中没有真正的面向对象的函数指针.这一点对C++来说是不幸的,因为面向对象的指针(也叫做"闭包(clo ...

  7. VB.NET中使用Linq TO SQL添加数据后获得自增长列ID

    VB.NET中使用Linq TO SQL添加数据后获得自增长列ID: Dim tempOrdre As New Order With { .CustomerID = cmbCustomerName.S ...

  8. VB.NET中DataGridView控件

    VB.NET中对于表格数据的显示经常使用到DataGridView控件,其以丰富多样的数据表呈现形式被程序猿喜爱. 本人在做一个小系统中运用DataGridView控件的部分属性,这些功能的使用在使用 ...

  9. vb.net中存储过程的使用

    在机房收费系统过程中,试着使用了存储过程,离之前数据库的学习已经有些日子了.之前对于存储过程的了解也是听过而已,非常不清楚.因此,写这篇博客! 专业概念:存储过程是一个SQL语句和控制结构的集合,创建 ...

随机推荐

  1. 基于C#实现的单点登录

    了解或想探索单点登录的朋友应该对单点登录有一个大致的了解,在这里我不在过多的阐述单点登录的概念. 单点登录说的通俗一点,就是一处登录(统一认证中心--Server),处处通行(Client). 一.第 ...

  2. vue中自定义指令

    //vue中自定义指令 //使用 Vue.directive(id, [definition]) 定义全局的指令 //参数1:指令的名称.注意,在定义的时候,指令的名称前面,不需要加 v-前缀; 但是 ...

  3. Django 中自定义 Admin 样式与功能

    目录 自定义 Admin 样式与功能 1 页面修改中文 1.1 语言设置为中文 1.2 应用管理设置为中文 1.3 数据库表设置为中文 1.4 数据库表字段名称修改为中文 2 修改后台样式 2.1 安 ...

  4. QT制作一个位图画图板程序

    本文学习如何创建一个Qt绘制程序,用户将能够通过使用不同的尺寸和画笔的颜色来表达他们的创造力. 主要功能:保存画板内容为图片.清除画板内容.设置画板大小.设置画笔颜色 新建基于QMainWindow的 ...

  5. MongoDB的集群模式--Sharding(分片)

    分片是数据跨多台机器存储,MongoDB使用分片来支持具有非常大的数据集和高吞吐量操作的部署. 具有大型数据集或高吞吐量应用程序的数据库系统可能会挑战单个服务器的容量.例如,高查询率会耗尽服务器的CP ...

  6. Golang: 打印命令行参数

    记得最早在学校机房学习 Java 时,照着书上的例子,写一个最简单 main 方法,当程序运行并在屏幕上打印出 hello world 时,内心竟有种莫名的激动,相信很多人都有这种经历吧. 不管学什么 ...

  7. mongodb 通过嵌入文档中的字段排序

    mongodb中的全部数据: db.testInfo.find({}) .sort({_id:-1}) .limit(100) 查询结果: /* 1 createdAt:2019/10/11 下午5: ...

  8. 让Windows中的文件名支持大小写

    背景 最近在Linux官网下载了Linux内核,下载下来的是一个后缀为.tar.xz的压缩包,于是在毫不知情的情况下随随便便解压了,解压过程中出现了很多问题. 其中一个问题就是在Windows下,不区 ...

  9. 【解决】修改 docker 容器时间与宿主机不同

    修改 docker 容器时间 需求: 这几天,开发提了个需求 "测试需要模拟未来某天的业务,发现容器里面没有修改时间的权限",想在我们 k8s 集群上,调整容器时间 解决方案: 使 ...

  10. docker中使用阿里云的apt源安装各种实用工具

    今天想在docker中安装vim工具,还有其他的软件等等,如果你直接执行apt-get install vim是没有用的,会显示: root@7d43d83fd3a8:/etc/nginx# apt- ...