由于机房收费系统中有很多一样的窗体,于是就想把同一类的窗体抽象出来作为一个类,其他的窗体去继承抽象窗体就可以了。
一、重复性窗体
学生充值记录,上机记录查看等窗体一样:
组合查询还有一类:操作员工作记录,学生信息维护,上机状态查询,学生上机信息统计:
我们来举个例子:组合窗体查询
二、举例说明:组合窗体查询为例
1、大概步骤:
首先建立一个组合窗体,让其他的窗体继承这个窗体,然后在父窗体中添加两个虚方法,在子窗体中重写虚方法,然后这样在B层,D层只需要用一个方法即可。
2、继承窗体
继承窗体,在创建的时候选继承窗体即可,然后选上是继承哪个窗体。如下图:
这样继承窗体就建好了。接下来我们再看代码部分。
三、代码部分
父窗体代码
'/*************************************************
'作者:刘腾腾
'说明:组合查询的父窗体,抽象类
'创建日期: 2013年4月30日
'版本号:机房收费v1.0
'**********************************************/
Public Class frmGroupQuery
Protected enQueryGroup As New Entity.QueryGroupEntity
''' <summary>
''' 退出
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks>刘腾腾 2013年4月30日</remarks>
Private Sub btnExit_Click(sender As Object,e As EventArgs) Handles btnExit.Click
Me.Close() '关闭
End Sub
''' <summary>
''' 查询按钮,Click事件
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks>刘腾腾 2013年4月30日</remarks>
Private Sub btnQuery_Click(sender As Object,e As EventArgs) Handles btnQuery.Click
'限制不能输入为空
If cmbRelation1.Text = "" Then
Dim arrayControl() As Control
ReDim Preserve arrayControl(2)
arrayControl(0) = cmbFields1 '字段1
arrayControl(1) = cmbOperator1 '操作符1
arrayControl(2) = txtContext1 '要输入的内容1
'调用函数SomeEmptyText判断控件中内容是否为空
If EmptyUI.SomeEmptyText(arrayControl) Then
Exit Sub
End If
End If
'根据组合框下拉菜单中是否有内容判断下一个查询条件控件中的内容是否为空
If cmbRelation1.Text <> "" Then
Dim arrayControl() As Control '定义函数
ReDim Preserve arrayControl(6) '函数的最小值为6
arrayControl(0) = cmbFields1 '字段1
arrayControl(1) = cmbOperator1 '操作符1
arrayControl(2) = txtContext1 '要输入的内容1
arrayControl(3) = cmbRelation1 '组合关系1
arrayControl(4) = cmbFields2 '字段2
arrayControl(5) = cmbOperator2 '操作符2
arrayControl(6) = txtContext2 '要输入的内容2
'调用函数SomeEmptyText判断控件中的内容是否为空
If EmptyUI.SomeEmptyText(arrayControl) Then
Exit Sub
End If
End If
'根据第二个组合框下拉菜单中是否有内容判断下一个查询条件中控件内容是否为空
If cmbRelation2.Text <> "" Then
If EmptyUI.AllEmptyText(Me) Then
Exit Sub
End If
End If
Dim dt As New DataTable '定义dt为datatable类型变量
Dim queryOperator As New Facade.UserFAC '实例化外观
'将参数传递给实体enQueryGroup
enQueryGroup.Fileds1 = answer(cmbFields1.Text) '字段名1
enQueryGroup.Fileds2 = answer(cmbFields2.Text) '字段名2
enQueryGroup.Fileds3 = answer(cmbFields3.Text) '字段名3
enQueryGroup.Operator1 = cmbOperator1.Text '操作符1
enQueryGroup.Operator2 = cmbOperator2.Text '操作符2
enQueryGroup.Operator3 = cmbOperator3.Text '操作符3
enQueryGroup.Context1 = txtContext1.Text.Trim '要输入内容1
enQueryGroup.Context2 = txtContext2.Text.Trim '要输入内容2
enQueryGroup.Context3 = txtContext3.Text.Trim '要输入内容3
enQueryGroup.Relation1 = answer(cmbRelation1.Text) '组合关系1
enQueryGroup.Relation2 = answer(cmbRelation2.Text) '组合关系2
enQueryGroup.Table = GetTable() '表名,通过调用一个函数来获取表名
'将查询的结果给表并显示
dt = queryOperator.QueryOperatorFAC(enQueryGroup)
If dt.Rows.Count > 0 Then '判断查询结果是否为空
dgvOperator.DataSource = dt '给DataGridView控件赋值
Else
dgvOperator.DataSource = Nothing '如果查询的内容为空,则提示没有记录
MsgBox("没有记录!","提示")
End If
End Sub
''' <summary>
''' 定义虚函数answer,根据选择条件的不同转换成不同的数据库字段
''' </summary>
''' <param name="GetResult">参数,根据comBox控件内容的不同获取不同结果</param>
''' <returns>返回GetResult,根据选择条件的不同转换成不同的数据库字段</returns>
''' <remarks>刘腾腾 2013年4月30日</remarks>
Protected Overridable Function answer(ByVal GetResult As String) As String
Return "" '返回值
End Function
''' <summary>
''' 定义虚函数GetTable,获取不同数据库的表名
''' </summary>
''' <returns>返回获取不同数据库的表名或者视图</returns>
''' <remarks>刘腾腾 2013年4月30日</remarks>
Protected Overridable Function GetTable() As String
Return ""
End Function
''' <summary>
''' 窗体加载,赋初值
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks>刘腾腾 2013年4月30日</remarks>
Private Sub frmOperatorRecord_Load(sender As Object,e As EventArgs) Handles MyBase.Load
'将参数传递给实体enQueryGroup,赋初值
enQueryGroup.Fileds1 = "1" '字段名1
enQueryGroup.Fileds2 = "1" '字段名2
enQueryGroup.Fileds3 = "1" '字段名3
enQueryGroup.Operator1 = "=" '操作符1
enQueryGroup.Operator2 = "=" '操作符2
enQueryGroup.Operator3 = "=" '操作符3
enQueryGroup.Context1 = "1" '要输入内容1
enQueryGroup.Context2 = "1" '要输入内容2
enQueryGroup.Context3 = "1" '要输入内容3
enQueryGroup.Relation1 = "and" '组合关系1
enQueryGroup.Relation2 = "and" '组合关系2
End Sub
子窗体代码
'/*************************************************
'作者:刘腾腾
'说明:操作员工作记录查询之组合查询
'创建日期: 2013年4月30日
'版本号:机房收费v1.0
'**********************************************/
''' <summary>
''' 操作员上机记录查询
''' </summary>
''' <remarks>刘腾腾 2013年4月30日</remarks>
Public Class frmGroupOperator
''' <summary>
''' 重写虚方法answer
''' </summary>
''' <param name="GetResult">用到参数GetResult,返回选择的comBox下拉菜单中的选项在数据库中的名称</param>
''' <returns>根据下拉菜单中选择内容转换成相应的数据库字段名</returns>
''' <remarks>刘腾腾 2013年4月30日</remarks>
Protected Overrides Function answer(GetResult As String) As String
'根据Select case语句进行转换
Select Case GetResult
Case "教师"
Return "userName"
Case "上班日期"
Return "loginDate"
Case "上班时间"
Return "loginTime"
Case "下班日期"
Return "logoutDate"
Case "下班时间"
Return "logoutTime"
Case "机器名"
Return "computer"
Case "或"
Return "or"
Case "与"
Return "And"
Case Else
Return ""
End Select
End Function
''' <summary>
''' 重写虚方法GetTable,给表赋值
''' </summary>
''' <returns>返回表名T_Worklog</returns>
''' <remarks>刘腾腾 2013年4月30日</remarks>
Protected Overrides Function GetTable() As String
enQueryGroup.Table = "T_Worklog" '给实体中属性赋值,将表名传进来
Return "T_Worklog" '返回结果,表名
End Function
End Class
这样就写好了。
四、总结:
用了模板方法把公共的行为提取到抽象类中,把不变的行为写在父类中,可变的行为在方法的子类中去实现。最大的感受就是代码的复用性提高了,减少了冗余代码和重复性代码,再也不用把那些重复性的代码搬来搬去了。
原文链接:https://www.f2er.com/vb/258971.html