浅谈继承窗体
重构时,大家一定发现了:很多窗体的整体的布局都非常类似。我们完全可以一个一个的添加窗体,然后将其中摆放好的控件复制到另一个窗体上,这样无可非议。不过总是粘贴复制就会有不好的味道在里面。
其实窗体也可以继承。今天就小谈下继承窗体。
我稍稍归纳了一下,在我们机房收费系统中,大体有这些窗体非常类似:学生上机记录查看,学生充值记录,他们是这样的窗体:
图一
金额收取信息查询、金额退还信息查询,他们是这样的窗体:
图二
学生上机信息统计、操作员工作记录、上机状态查询、学生基本信息维护,是这样的窗体:
图三
除了窗体的名字不同,其他的我们看上去都是一样的。这样,我们就可以对它们使用继承窗体。
其实,继承窗体也属于我们平时所说的泛化继承。我们在创建时,只需要添加一个窗体,让他作为父窗体,将一些共有的属性方法提炼出来,写在该父窗体中。Click事件或者Load中公共的代码等等,我们都可以写在父窗体中。比如图三中关于组合框、文本框是否为空的判断,我们就可以将其整体性的放在父窗体中,甚至对于BLL层的调用,我们也可以将其放在父窗体中,达到极大程度的复用。
子窗体的创建,我试过两种方法。一种是直接在添加一个空白窗体,在上面写上” : Inherits Form2”这样的字样。就是下面的写法:
Public Class Form1 : Inherits Form
end Class
这样的继承窗体需要注意的是被继承的窗体要先生成dll,然后在继承的窗体中引用此Dll文件才可以。
另一种方法是选择添加窗体,然后在左边模版处找到“Windows Forms”,然后在所列的窗体类型中选择“继承窗体”,接下来只需要选择你刚刚创建的父窗体就可以了。
如下图:
这样就创建成功了。在使用时,也有几点需要我们注意。
子窗体功能与父窗体功能不同的地方,我们要在父窗体相应的事件Overridable,并将其关键字改为Protected。对于子窗体相应功能,我们也需要注意加上Overrides关键字。之后,我们就可以享受继承窗体给我带来的快感了。
下面是我组合查询父窗体代码:
'定义实体类数组,用于向BLL层传递 Dim arrayInfo() As Entity.FatherInq ''' <summary> ''' 判断文本框 ''' </summary> ''' <param name="txtField"></param> ''' <remarks></remarks> Public Function IsExistBox(ByVal txtField As TextBox) As Boolean If txtField.Text.Trim = "" Then MessageBox.Show(txtField.Tag.ToString & "不能为空,请输入信息!", "温馨提示") txtField.Focus() Return False Else Return True End If End Function ''' <summary> ''' 判断组合框 ''' </summary> ''' <param name="ComField"></param> ''' <remarks></remarks> Public Function IsExistComBox(ByVal ComField As ComboBox) As Boolean If ComField.Text.Trim = "" Then MessageBox.Show(ComField.Tag.ToString & "不能为空,请选择信息", "温馨提示") ComField.Focus() Return False Else Return True End If End Function ''' <summary> ''' 组合框内容的添加 ''' </summary> ''' <param name="cmbBox"></param> ''' <param name="StrContext"></param> ''' <remarks></remarks> Protected Sub AddContext(ByVal cmbBox As ComboBox, ByVal StrContext As String()) cmbBox.Items.AddRange(StrContext) End Sub Protected Sub frmFactherInq_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load lblInq.Text = "选择" & Chr(10) & Chr(13) & "查询" & Chr(10) & Chr(13) & "条件" Dim strOper() As String = {"", "=", ">", "<", "<>"} Dim strRelation() As String = {"", "与", "或"} Dim Strc As String comOper.Items.AddRange(strOper) comOperOne.Items.AddRange(strOper) comOperTwo.Items.AddRange(strOper) For Each Strc In strRelation comRelationOne.Items.Add(Strc) comRelationTwo.Items.Add(Strc) Next End Sub Protected Function GetInfo(ByVal comField As ComboBox(), ByVal comOpers As ComboBox(), ByVal txtContexts As String(), ByVal comRelations As ComboBox()) As Entity.FatherInq() arrayInfo = {New Entity.FatherInq(), New Entity.FatherInq(), New Entity.FatherInq()} '对第一个参数进行赋值 arrayInfo(0).Field = comField(0).Text arrayInfo(0).Oper = comOpers(0).Text arrayInfo(0).Context = txtContexts(0) '对第一个关系进行赋值 If comRelationOne.Text = "" Then arrayInfo(1).Field = comField(0).Text arrayInfo(2).Field = comField(0).Text arrayInfo(1).Oper = comOpers(0).Text arrayInfo(2).Oper = comOpers(0).Text arrayInfo(1).Context = txtContexts(0) arrayInfo(2).Context = txtContexts(0) Return arrayInfo End If If comRelationOne.Text = "或" Then arrayInfo(1).Relation = "or" End If '对第二个参数进行赋值 If comField(1).Text = "" Then arrayInfo(1).Field = comField(0).Text Else arrayInfo(1).Field = comField(1).Text End If If comOperOne.Text = "" Then arrayInfo(1).Oper = comOpers(0).Text Else arrayInfo(1).Oper = comOpers(1).Text End If If txtContext.Text = "" Then arrayInfo(1).Context = txtContexts(0) Else arrayInfo(1).Context = txtContexts(1) End If '对第二个关系进行赋值 If comRelationTwo.Text = "" Then arrayInfo(2).Field = comField(0).Text arrayInfo(2).Oper = comOpers(0).Text arrayInfo(2).Context = txtContexts(0) Return arrayInfo End If If comRelationTwo.Text = "或" Then arrayInfo(2).Relation = "or" End If '对第三个参数进行赋值 If comField(2).Text = "" Then arrayInfo(2).Field = comField(0).Text Else arrayInfo(2).Field = comField(2).Text End If If comOperOne.Text = "" Then arrayInfo(2).Oper = comOpers(0).Text Else arrayInfo(2).Oper = comOpers(2).Text End If If txtContext.Text = "" Then arrayInfo(2).Context = txtContexts(0) Else arrayInfo(2).Context = txtContexts(2) End If Return arrayInfo End Function '下面不可省略,供子窗体重写 Protected Overridable Sub cmdOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdOK.Click End Sub Private Sub cmdCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdCancel.Click Me.Close() End Sub Protected Sub txtContext_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles txtContext.KeyPress, txtContextOne.KeyPress, txtContextTwo.KeyPress If e.KeyChar = Chr(39) Or e.KeyChar = Chr(61) Then e.Handled = True Else e.Handled = False End If End Sub
这样,在子窗体UI层只需要进行简单的逻辑判断,调用BLL层的相关功能就可以了。