致力于技术进步

专注于编程艺术

博客园 首页 新随笔 联系 订阅 管理
相信开发者都会碰到如下问题,就是经常要用到(代号+名称)结合出现的情况,
如:要用代号来查询选出名称, 下面是我写的一个用户自定义控件,可以有三种方式
来查询,一:利用要查出资料的任何一列来进行模糊查找(代号或助记码或名称);
二:利用选择任一个列来查询(在选择框中选择代号或助记码或名称);三:设计时
固定来哪一个列用于查询(如设只能用代号来查询),下面是一部分代号,如果谁需
要更详细的设计方法,请与作者联系,QQ:41677881。
'查找种类
Public Enum emFindStyle As Integer

    AllFindKey = 1      '全部
    OneFindKey = 2      '只有一个,可以在查询框选择
    OneFixedKey = 3     '只有一个,编程时设定

End Enum

'显示风格
Public Enum emShowStyle As Integer

    KeyDownShow = 1   'KeyDown显示查询框
    GotFocusShow = 2  'GotFocus显示查询框

End Enum

Public Class MySmartFind

#Region " 构造函数 "

    Sub New()

        ' 此调用是 Windows 窗体设计器所必需的。
        InitializeComponent()
        ' 在 InitializeComponent() 调用之后添加任何初始化。

        '属性预设值
        Me.NoText = "预设代号"
        Me.NoControlWidth = 100
        Me.NoColumnName = ""
        Me.NoColumnWidth = Me.txtNo.Width  '100
        Me.NameText = "预设名称"
        Me.NameColumnName = ""
        Me.NameColumnWidth = Me.labName.Width '250
        Me.FindStyle = emFindStyle.AllFindKey
        Me.OneFindKeyColumn = ""
        Me.ShowStyle = emShowStyle.KeyDownShow
        Me.DistinguishUpperAndLower = False

    End Sub

#End Region

#Region " 变量 "

    '变量
    Private _NoText As String                       '代号
    Private _NoControlWidth As Integer              '代号控件宽度
    Private _NoColumnName As String                 '代号列名
    Private _NoColumnWidth As Integer               '代号列宽度
    Private _NameText As String                     '名称
    Private _NameColumnName As String               '名称列名
    Private _NameColumnWidth As Integer             '名称列宽度
    Private _DataSource As DataTable                '数据源
    Private _FindStyle As emFindStyle               '查询方式
    Private _OneFindKeyColumn As String             '唯一下个查询键字段名
    Private _ShowStyle As emShowStyle               '何时显示查询框
    Private _DistinguishUpperAndLower As Boolean    '区别大小写
    Private _frmSmartFind As frmSmartFind           '查询窗体
    Private intFocusFlag As Integer                 'GotFocus是否起用标志


#End Region

#Region " 属性 "

    '属性
    Public Property NoText() As String
        Get
            Return _NoText
        End Get
        Set(ByVal value As String)
            Try
                If value Is Nothing Then
                    value = ""
                Else
                    value = CType(value, String)
                End If
            Catch ex As Exception
                Throw New Exception("NoText必须为String类型")
            End Try
            _NoText = value
            txtNo.Text = _NoText
        End Set
    End Property
    Public Property NoControlWidth() As Integer
        Get
            Return _NoControlWidth
        End Get
        Set(ByVal value As Integer)
            _NoControlWidth = value
            txtNo.Width = _NoControlWidth
            'labName.Width = labName.Width - _NoWidth
            labName.Location = New Point(txtNo.Location.X + _NoControlWidth, labName.Location.Y)

        End Set
    End Property
    Public Property NoColumnName() As String
        Get
            Return _NoColumnName
        End Get
        Set(ByVal value As String)
            Try
                If value Is Nothing Then
                    value = ""
                Else
                    value = CType(value, String)
                End If
            Catch ex As Exception
                Throw New Exception("NoColumn必须为String类型")
            End Try
            _NoColumnName = value
        End Set
    End Property
    Public Property NoColumnWidth() As Integer
        Get
            Return _NoColumnWidth
        End Get
        Set(ByVal value As Integer)
            _NoColumnWidth = value
        End Set
    End Property
    Public Property NameText() As String
        Get
            Return _NameText
        End Get
        Set(ByVal value As String)
            Try
                If value Is Nothing Then
                    value = ""
                Else
                    value = CType(value, String)
                End If
            Catch ex As Exception
                Throw New Exception("NameText必须为String类型")
            End Tr
y
            _NameText = value
            labName.Text = _NameText
        End Set
    End Property
    Public Property NameColumnName() As String
        Get
            Return _NameColumnName
        End Get
        Set(ByVal value As String)
            Try
                If value Is Nothing Then
                    value = ""
                Else
                    value = CType(value, String)
                End If
            Catch ex As Exception
                Throw New Exception("NameColumn必须为String类型")
            End Try
            _NameColumnName = value
        End Set
    End Property
    Public Property NameColumnWidth() As Integer
        Get
            Return _NameColumnWidth
        End Get
        Set(ByVal value As Integer)
            _NameColumnWidth = value
        End Set
    End Property
    Public Property DataSource() As DataTable
        Get
            Return _DataSource
        End Get
        Set(ByVal value As DataTable)
            If value Is Nothing Then
                _DataSource = Nothing
            Else
                _DataSource = value.Copy
                '去除Table中所有值的空格
                Call clrEmptyInTable(_DataSource)
            End If

        End Set

    End Property
    Public Property FindStyle() As emFindStyle
        Get
            Return _FindStyle
        End Get
        Set(ByVal value As emFindStyle)
            _FindStyle = value
        End Set
    End Property
    Public Property OneFindKeyColumn() As String
        Get
            Return _OneFindKeyColumn
        End Get
        Set(ByVal value As String)
            Try
                If value Is Nothing Then
                    value = ""
                Else
                    value = CType(value, String)
                End If
            Catch ex As Exception
                Throw New Exception("OneFindKeyColumn必须为String类型")
            End Try
            _OneFindKeyColumn = value
        End Set
    End Property
    Public Property ShowStyle() As emShowStyle
        Get
            Return _ShowStyle
        End Get
        Set(ByVal value As emShowStyle)
            _ShowStyle = value
        End Set
    End Property
    Public Property DistinguishUpperAndLower() As Boolean
        Get
            Return _DistinguishUpperAndLower
        End Get
        Set(ByVal value As Boolean)
            _DistinguishUpperAndLower = value
        End Set
    End Property


#End Region#Region " 自定义事件 "

    Public Event NoTextChanged(ByVal sender As Object, ByVal e As System.EventArgs)
    Public Event NoTextKeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs)
    Public Event NameTextChanged(ByVal sender As Object, ByVal e As System.EventArgs)

#End Region
#Region " 事件 "

    Private Sub txtNo_GotFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtNo.GotFocus

        txtNo.SelectAll()
        If ShowStyle = emShowStyle.GotFocusShow Then
            If intFocusFlag = 1 Then Exit Sub
            If _frmSmartFind Is Nothing Then

                '显示查询框,进行查询
                Call showSmartFind()

            End If
            intFocusFlag = 0
        End If

    End Sub

    Private Sub txtNo_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles txtNo.KeyDown


        If e.KeyData = Keys.Enter Then

            If _frmSmartFind Is Nothing Then

                '显示查询框,进行查询
                Call showSmartFind()

                txtNo.Focus()
                txtNo.SelectAll()

            End If

        End If

        '引发自定义事件
        RaiseEvent NoTextKeyDown(Me, e)

    End Sub

    Private Sub txtNo_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtNo.TextChanged

        If Me.DataSource Is Nothing Or Me.NoColumnName = "" Or Me.NameColumnName = "" Then
            Exit Sub
        End If
        If Me.FindStyle = emFindStyle.OneFixedKey And Me.OneFindKeyColumn = "" Then
            Exit Sub
        End If
        labName.Text = ""
        '在DataView中根据代码查找名称
        If txtNo.Text.Trim <> "" And Me.DataSource IsNot Nothing Then
            'labName.Text = getName
FromNo(DataSource.DefaultView, strNo, Me.NoColumn, Me.NameColumn)
            labName.Text = getNameFromNo()
        End If

        '引发自定义事件
        RaiseEvent NoTextChanged(Me, New System.EventArgs)

    End Sub

    Private Sub labName_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles labName.TextChanged

        '引发自定义事件
        RaiseEvent NameTextChanged(Me, New System.EventArgs)

    End Sub

#End Region
#Region " 方法 "

    '设置查询窗体位置,在些控件下方,或根据窗体位置调整
    Private Sub setFormLocation(ByVal frm As frmSmartFind)

        Dim frmParent As Control
        Dim intFormX As Integer = Me.Left
        Dim intFormY As Integer = Me.Top + Me.Height
        Dim intScrW As Integer = Screen.PrimaryScreen.Bounds.Width  '取得屏幕宽度
        Dim intScrH As Integer = Screen.PrimaryScreen.Bounds.Height '取得屏幕高度

        frmParent = Me
        '累加父控件至左侧的距离,直到最后包含的窗体(包括最终容器form)
        While (frmParent.Parent IsNot Nothing)

            frmParent = frmParent.Parent
            intFormX += frmParent.Left
            intFormY += frmParent.Top

        End While

        '如果些查询窗体的width加上它离总Form左侧的距离>屏幕宽度,则查询窗体向左放
        If intFormX + frm.Width > intScrW Then

            frm.Left = intFormX - frm.Width + Me.Width + 3  '3为Form左边缘的宽度
        Else

            frm.Left = intFormX + 3     '3为Form左边缘的宽度

        End If


        '如果些查询窗体的Height加上它离总Form上侧的距离>屏幕高度,则查询窗体向上放
        If intFormY + frm.Height > intScrW Then

            frm.Top = intFormY - frm.Height + Me.Height + 29 '29为Form标题列的高度
        Else

            frm.Top = intFormY + 29   '29为Form标题列的高度
        End If

    End Sub

    '显示查询框,进行查询
    Private Sub showSmartFind()

        If Me.DataSource Is Nothing Then
            MessageBox.Show("此控件必须设置DataSource", Me.Name & "--警告", MessageBoxButtons.OK, MessageBoxIcon.Warning)
            Exit Sub
        End If
        If Me.NoColumnName = "" Then
            MessageBox.Show("此控件必须设置NoColumnName", Me.Name & "--警告", MessageBoxButtons.OK, MessageBoxIcon.Warning)
            Exit Sub
        End If
        If Me.NameColumnName = "" Then
            MessageBox.Show("此控件必须设置NameColumnName", Me.Name & "--警告", MessageBoxButtons.OK, MessageBoxIcon.Warning)
            Exit Sub
        End If
        If Me.FindStyle = emFindStyle.OneFixedKey And Me.OneFindKeyColumn = "" Then
            MessageBox.Show("此控件必须先设置OneFindKeyColumn", Me.Name & "--警告", MessageBoxButtons.OK, MessageBoxIcon.Warning)
            Exit Sub
        End If

        Dim strNo As String                 '存放代号
        strNo = txtNo.Text.Trim.ToUpper     '不区分大小写,统一变为大写后查询

        If _frmSmartFind Is Nothing Then
            _frmSmartFind = New frmSmartFind(DataSource, NoColumnName, NoColumnWidth, NameColumnName, NameColumnWidth, FindStyle, strNo, OneFindKeyColumn)
        End If

        '设置查询窗体位置,在些控件下方,或根据窗体位置调整
        Call setFormLocation(_frmSmartFind)

        If _frmSmartFind.ShowDialog() = DialogResult.OK Then
            txtNo.Text = _frmSmartFind.strNo
            labName.Text = _frmSmartFind.strName
        End If

        _frmSmartFind = Nothing

    End Sub

    '去除Table中所有值的空格
    Private Sub clrEmptyInTable(ByVal dt As DataTable)

        For intLoopI As Integer = 0 To dt.Rows.Count - 1

            For intLoopJ As Integer = 0 To dt.Columns.Count - 1
                dt.Rows(intLoopI).Item(intLoopJ) = dt.Rows(intLoopI).Item(intLoopJ).ToString.Trim
            Next

        Next

    End Sub

    '在DataView中根据代码查找名称
    Private Function getNameFromNo() As String

        Dim dvTmp As DataView = DataSource.DefaultView
        dvTmp.RowFilter = ""
        Dim strNo As String                 '存放代号
        If DistinguishUpperAndLower = False Then
            strNo = txtNo.Text.Trim.ToUpper     'false 不区分大小写,统一变为大写
        Else
            strNo = txtNo.Text.Trim             'true 区分大小写
        End If

        Select Case FindStyle
            Case MyControlLibrary.emFindStyle.AllFindKey

                '只能实现用代号查出名称
                For intLoop As Integer = 0 To dvTmp.Count - 1
                    Dim strNoFromTable As String            '存储Table中的要比较的值
                    If DistinguishUpperAndLower = False Then
                        'false 不区分大小写,统一变为大写
                        strNoFromTable = dvTmp.Item(intLoop).Item(NoColumnName).ToString.Trim.ToUpper
                    Else
                        'true 区分大小写
                        strNoFromTable = dvTmp.Item(intLoop).Item(NoColumnName).ToString.Trim
                    End If
                    If strNoFromTable = strNo Then
                        '查找成功,返回所在行的所查列的内容
;  Return dvTmp.Item(intLoop).Item(NameColumnName).ToString.Trim
                    End If
                Next

            Case MyControlLibrary.emFindStyle.OneFindKey

                '只能实现用代号查出名称
                For intLoop As Integer = 0 To dvTmp.Count - 1
                    Dim strNoFromTable As String            '存储Table中的要比较的值
                    If DistinguishUpperAndLower = False Then
                        'false 不区分大小写,统一变为大写
                        strNoFromTable = dvTmp.Item(intLoop).Item(NoColumnName).ToString.Trim.ToUpper
                    Else
                        'true 区分大小写
                        strNoFromTable = dvTmp.Item(intLoop).Item(NoColumnName).ToString.Trim
                    End If
                    If strNoFromTable = strNo Then
                        '查找成功,返回所在行的所查列的内容
                        Return dvTmp.Item(intLoop).Item(NameColumnName).ToString.Trim
                    End If
                Next

            Case MyControlLibrary.emFindStyle.OneFixedKey

                Dim intFlag As Integer = 0      '存储查出的笔数
                Dim strTmpNo As String = ""     '存储临时的代号
                Dim strBackName As String = ""  '存储回传的名称
                '有指定的固定的查询键查出名称
                For intLoop As Integer = 0 To dvTmp.Count - 1
                    Dim strNoFromTable As String            '存储Table中的要比较的值
                    If DistinguishUpperAndLower = False Then
                        'false 不区分大小写,统一变为大写
                        strNoFromTable = dvTmp.Item(intLoop).Item(NoColumnName).ToString.Trim.ToUpper
                    Else
                        'true 区分大小写
                        strNoFromTable = dvTmp.Item(intLoop).Item(NoColumnName).ToString.Trim
                    End If

                    If strNoFromTable = strNo Then
                        '返回代号值,因为可能并非用代号在查
                        strTmpNo = strNoFromTable
                        '查找成功,返回所在行的所查列的内容
                        strBackName = dvTmp.Item(intLoop).Item(NameColumnName).ToString.Trim
                        intFlag += 1
                    End If
                Next
                If intFlag <> 1 Then
                    Return ""
                Else
                    txtNo.Text = strTmpNo
                    Return strBackName
                End If

        End Select

        '查找失败,返回空
        Return ""

    End Function
posted on 2007-12-10 16:24  stephen&amp;#183;周  阅读(836)  评论(1)    收藏  举报