机房重构——组合查询


组合查询用到了模板方法,体会了继承窗体的魅力,省了很多劲。大体思路是这样的:窗体一加载第一行查询条件的控件和第一个选择关系的框可用,并且关系组合框的内容显示为<请选择>,如果关系组合框的内容是and或是or,第二行和第二个关系组合框可用,类似入伙第二个关系组合框选好了关系,第三行可用。主要解决了两个问题:1.字段选中后,如何根据字段内容自动显示操作符。2.如何根据字段内容 显示“要查找的内容”是用text框还是DTpicker。3. 字段组合框中的中文内容如何与数据库中的字段名对应

字段内容决定操作符内容和要查内容的容器

解决第一和第二个问题,用到了虚方法和循环。 虚方法实现了子窗体与父窗体之间的交互,父窗体就是一个框架,结构,具体窗体里应该加什么字段这些特殊的东西可以通过重写父窗体中的虚方法实现。

 ''' <summary>
    ''' 虚方法 获得需要用4个比较符号的字段的值
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Protected Overridable Function GetCmbFieldText() As String()
        Return {""}
    End Function
 ''' <summary>
    ''' 定义虚方法 返回字段中需要对应日期的值
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Protected Overridable Function GetDate() As String()
        Return {""}
    End Function
 ''' <summary>
    ''' 定义虚方法 返回字段中需要对应时间的值
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Protected Overridable Function GetTime() As String()
        Return {""}
    End Function
 ''' <summary>
    ''' 字段一内容改变时,检查是否是需要4种符号,如果是在操作符种显示4种,否则显示两种。加载的时候默认的是两种
    ''' 字段内容改变,判断是不是时间或日期类型的,如果是,把txtcontent用dtpicker 遮住
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    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


在窗体加载的时候,就把字段的中英文对应弄好,并把字段组合框里添加上内容

 ''' <summary>
    ''' 加载时给窗体控件添加信息 
    ''' 用到了哈希表 把字段中的中文和对应的英文用哈希表表示
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    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
''' <summary>
    ''' 虚方法获得字段名
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Protected Overridable Function GetFieldName() As String()
        Return {""}
    End Function
  ''' <summary>
    ''' 虚方法获得字段对应的英文名
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Protected Overridable Function GetDBName() As String()
        Return {""}
    End Function
 '虚方法获得关系是或还是与 从而确定用or还是and
    Protected Overridable Function GetRelationName(relation As String) As String
        Return ""
    End Function
  ''' <summary>
    ''' 虚方法获得查询的数据表
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    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
''' <summary>
    ''' 当DTPicker的值改变是就把DTPicker 的值按照规定形式传给text,因为在单击查询,给实体传参的时候一律用的是text框的值
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    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

小结
模板方法非常适合这种有好多类似窗体的使用,提高效率。其中应用了很多虚方法和循环,也尝试的使用了哈希表,学习就是一个不断积累的过程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 43
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 43
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值