组合查询用到了模板方法,体会了继承窗体的魅力,省了很多劲。大体思路是这样的:窗体一加载第一行查询条件的控件和第一个选择关系的框可用,并且关系组合框的内容显示为<请选择>,如果关系组合框的内容是and或是or,第二行和第二个关系组合框可用,类似入伙第二个关系组合框选好了关系,第三行可用。主要解决了两个问题:1.字段选中后,如何根据字段内容自动显示操作符。2.如何根据字段内容 显示“要查找的内容”是用text框还是DTpicker。3. 字段组合框中的中文内容如何与数据库中的字段名对应
解决第一和第二个问题,用到了虚方法和循环。 虚方法实现了子窗体与父窗体之间的交互,父窗体就是一个框架,结构,具体窗体里应该加什么字段这些特殊的东西可以通过重写父窗体中的虚方法实现。
'''
''' 虚方法 获得需要用4个比较符号的字段的值
'''
'''
'''
Protected Overridable Function GetCmbFieldText() As String()
Return {""}
End Function
'''
''' 定义虚方法 返回字段中需要对应日期的值
'''
'''
'''
Protected Overridable Function GetDate() As String()
Return {""}
End Function
'''
''' 定义虚方法 返回字段中需要对应时间的值
'''
'''
'''
Protected Overridable Function GetTime() As String()
Return {""}
End Function
'''
''' 字段一内容改变时,检查是否是需要4种符号,如果是在操作符种显示4种,否则显示两种。加载的时候默认的是两种
''' 字段内容改变,判断是不是时间或日期类型的,如果是,把txtcontent用dtpicker 遮住
'''
'''
'''
'''
Private Sub cmbField1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cmbField1.SelectedIndexChanged
cmbOperation1.Items.Clear() '每次字段内容改变,操作符里的列表清空
DTPicker1.Visible = False 'dtpicker默认不可见
txtContent1.Text = "" '内容框为空,防止一直显示时间或日期
Dim field1Text() As String
field1Text = GetCmbFieldText() '获得虚方法传回来的字段中需要4个运算符的字段名
cmbOperation1.Items.AddRange({"=", "<>"}) '每次字段内容改变,运算符先加载这两个
'利用循环,如果字段中的内容是虚方法传回来的值,操作符就再加以下两个运算符
For Each F1Text As String In field1Text
If cmbField1.Text = F1Text And cmbOperation1.Items.Count < 4 Then
cmbOperation1.Items.AddRange({">", "<"})
End If
Next
'把操作符列表里的第一项反倒text中
cmbOperation1.Text = cmbOperation1.Items(0).ToString
'如果字段内容是虚方法返回的日期相关的内容,txtcontent位置显示dtpicker,把获得的日期转成字符串传给txtContent
Dim field1Date() As String
field1Date = GetDate()
For Each F1Date As String In field1Date
If cmbField1.Text = F1Date Then
DTPicker1.Visible = True
DTPicker1.Format = DateTimePickerFormat.Short
txtContent1.Text = Format(DTPicker1.Value, "yyyy-MM-dd").ToString
End If
Next
'如果字段内容是虚方法返回的日期相关的内容,txtcontent位置显示dtpicker的时间形式,把获得的日期转成字符串传给txtContent
Dim field1Time() As String
field1Time = GetTime()
For Each F1Time As String In field1Time
If cmbField1.Text = F1Time Then
DTPicker1.Visible = True
DTPicker1.Format = DateTimePickerFormat.Time
txtContent1.Text = Format(DTPicker1.Value, "hh:mm:ss").ToString
End If
Next
End Sub
解决这个问题用到了虚方法,和哈希表。因为字段中的中英文对应所以选择应用哈希表。
Public Class frmGroupQuery
Dim ht As New Hashtable '定义哈希表
Dim fieldName() As String '定义字符类型的集合来接受虚方法传回的字符集合
Dim DBName() As String
在窗体加载的时候,就把字段的中英文对应弄好,并把字段组合框里添加上内容
'''
''' 加载时给窗体控件添加信息
''' 用到了哈希表 把字段中的中文和对应的英文用哈希表表示
'''
''' ">
''' "e">
'''
Private Sub GroupQuery_Load(sender As Object, e As EventArgs) Handles MyBase.Load
fieldName = GetFieldName() '接收虚方法传回的字段的中文内容
DBName = GetDBName() '接收虚方法传回的字段对应的英文
For i = 0 To fieldName.Count - 1 '给哈希表赋值 键值都是字符类型 不能是集合
ht.Add(fieldName(i), DBName(i)) 'ht是哈希表
Next i
cmbField1.Items.AddRange(fieldName)
cmbField2.Items.AddRange(fieldName)
cmbField3.Items.AddRange(fieldName)
cmbField1.Text = cmbField1.Items(0).ToString
cmbRelation1.Items.AddRange({"或", "与", "<请选择>"})
cmbRelation2.Items.AddRange({"或", "与", "<请选择>"})
cmbRelation1.Text = cmbRelation1.Items(2).ToString
DTPicker1.Visible = False
DTPicker2.Visible = False
DTPicker3.Visible = False
'cmbOperation1.Text = cmbOperation1.Items(0).ToString
End Sub
'''
''' 虚方法获得字段名
'''
'''
'''
Protected Overridable Function GetFieldName() As String()
Return {""}
End Function
'''
''' 虚方法获得字段对应的英文名
'''
'''
'''
Protected Overridable Function GetDBName() As String()
Return {""}
End Function
'虚方法获得关系是或还是与 从而确定用or还是and
Protected Overridable Function GetRelationName(relation As String) As String
Return ""
End Function
'''
''' 虚方法获得查询的数据表
'''
'''
'''
Protected Overridable Function GetTable() As String
Return ""
End Function
在点击查询,检查各个输入框是否填好的时候,运用了循环减少代码量
Private Sub btnCheck_Click(sender As Object, e As EventArgs) Handles btnCheck.Click
'检查输入是否完整
Dim control As New Control
For Each control In GroupBox1.Controls
If control.Enabled = True Then
If control.Text = "" Then
MsgBox("请填写完整您要查询的条件", MsgBoxStyle.Exclamation, "提示")
Exit Sub
End If
End If
Next
'给实体层传参
Dim thisGroupQuery As New Entity.GroupQueryInfo '定义一个实体参数
'字段名找到对应的英文名称
Dim DBFieldName1 As String
Dim DBFieldName2 As String
Dim DBFieldName3 As String
DBFieldName1 = ht.Item(cmbField1.Text)
DBFieldName2 = ht.Item(cmbField2.Text)
DBFieldName3 = ht.Item(cmbField3.Text)
'给实体传参
thisGroupQuery.cmbField1_text = DBFieldName1
thisGroupQuery.cmbField2_text = DBFieldName2
thisGroupQuery.cmbField3_text = DBFieldName3
thisGroupQuery.cmbOperation1_text = cmbOperation1.Text.Trim()
thisGroupQuery.cmbOperation2_text = cmbOperation2.Text.Trim()
thisGroupQuery.cmbOperation3_text = cmbOperation3.Text.Trim()
thisGroupQuery.txtContent1_text = txtContent1.Text.Trim()
thisGroupQuery.txtContent2_text = txtContent2.Text.Trim()
thisGroupQuery.txtContent3_text = txtContent3.Text.Trim()
thisGroupQuery.cmbRelation1_text = GetRelationName(cmbRelation1.Text.Trim())
thisGroupQuery.cmbRelation2_text = GetRelationName(cmbRelation2.Text.Trim())
thisGroupQuery.getTable = GetTable()
'调用外观层组合查询的方法
Dim Facade As New Facade.GroupQueryFacade
Dim table As DataTable
table = Facade.GroupQuery(thisGroupQuery)
'根据泛型判断是否有要查询的记录
If table Is Nothing Then
MsgBox("没有要查询的记录!", MsgBoxStyle.Exclamation, "提示")
Else
dataGridview.DataSource = table
For i As Integer = 0 To DBName.Count - 1
dataGridview.Columns(DBName(i)).HeaderText = fieldName(i)
Next
End If
End Sub
Private Sub cmbRelation1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cmbRelation1.SelectedIndexChanged
Dim relation As String = cmbRelation1.Text.Trim
Select Case relation
Case "<请选择>"
cmbField2.Enabled = False
cmbOperation2.Enabled = False
txtContent2.Enabled = False
Case Is <> "<请选择>"
cmbField2.Enabled = True
cmbOperation2.Enabled = True
txtContent2.Enabled = True
cmbRelation2.Enabled = True
cmbField2.Text = cmbField2.Items(0).ToString
cmbOperation2.Text = cmbOperation2.Items(0).ToString
cmbRelation2.Text = cmbRelation2.Items(2).ToString
End Select
End Sub
'''
''' 当DTPicker的值改变是就把DTPicker 的值按照规定形式传给text,因为在单击查询,给实体传参的时候一律用的是text框的值
'''
'''
'''
'''
Private Sub DTPicker1_ValueChanged(sender As Object, e As EventArgs) Handles DTPicker1.ValueChanged
If DTPicker1.Format = DateTimePickerFormat.Short Then
txtContent1.Text = Format(DTPicker1.Value, "yyyy-MM-dd").ToString
End If
If DTPicker1.Format = DateTimePickerFormat.Time Then
txtContent1.Text = Format(DTPicker1.Value, "hh:mm:ss").ToString
End If
End Sub
小结
模板方法非常适合这种有好多类似窗体的使用,提高效率。其中应用了很多虚方法和循环,也尝试的使用了哈希表,学习就是一个不断积累的过程。