在DataGridView中进行渐进式搜索

You've probably seen a table that allows the user to start typing and moves immediately to the row whose key field starts with the characters you've typed. A ComboBox does a very rudimentary form of this: you type the first character, and it moves to the first match. But a progressive search is more powerful; as you type, say, S, M, I, T, with a list of names, it'll go first (in my local phone directory) to Saab, then to Smale, then to Smialkowski, then to Smith. The full list of names is still displayed, so the user can go up or down from wherever he lands with the search (unlike versions of progressive searches that filter the rows). You can undo a letter by pressing Backspace.

您可能已经看到了一个表,该表允许用户开始输入并立即移动到其键字段以您输入的字符开头的行。 ComboBox的功能非常简单:您输入第一个字符,然后移到第一个匹配项。 但是渐进式搜索功能更强大。 当您输入带有名称列表的S,M,I,T时,它将首先(在我的本地电话目录中)到达Saab,然后到达Smale,然后到达Smialkowski,再到Smith。 名称的完整列表仍会显示,因此用户可以在搜索到的任何位置上上下移动(与过滤行的渐进式搜索不同)。 您可以通过按Backspace键撤消字母。

While I've seen progressive searches in other languages that will highlight the letters entered in the list itself, there doesn't seem to be an easy way to highlight portions of text inside a DGV cell. So instead, this routine displays the text it's searching for in a separate label that is displayed elsewhere on the form (I put mine just above the key field of the DGV). One complication is that many punctuation characters must be enclosed in brackets, or they'll be considered to have special meanings, not to be characters to search for. The label display won't be necessarily the same as the internal search string.

虽然我看到了用其他语言进行的渐进式搜索将突出显示列表本身中输入的字母,但是似乎没有一种简单的方法来突出显示DGV单元格内的部分文本。 因此,此例程改为在单独的标签中显示要搜索的文本,该标签显示在表单的其他位置(我将我的文本放在DGV的关键字段上方)。 一种复杂的情况是,许多标点符号必须放在方括号中,否则它们将被视为具有特殊含义,而不是要搜索的字符。 标签显示不一定与内部搜索字符串相同。

This requires the DGV to use a DataSource that has the .Select method, such as a DataTable. Note that the search is case-insensitive, which is inherent in the use of LIKE in the Select statement.

这要求DGV使用具有.Select方法的DataSource,例如DataTable。 请注意,搜索不区分大小写,这是在Select语句中使用LIKE所固有的。

The basic methodology is:

基本方法是:

When the user enters a character, it is processed by the KeyPress event handler. Add it to the search string (with brackets around it if it's one of the punctuation characters that need it). Search the DataTable for records with fldKey that start with the letter(s) entered; if one or more records are found, move the current cell (which is highlighted on screen) to the first matching row. If no records are found, beep and ignore that character. If a Backspace is entered, remove the last character from the search string and find the first matching record of the shortened search string (if no search string is left, move to the first record). If the user moves via the up & down arrow, Page Up/Page Down, or clicking with the mouse, discard the search string and recognize the move.

用户输入字符时,将由KeyPress事件处理程序对其进行处理。 将其添加到搜索字符串中(如果它是需要它的标点字符之一,则用括号括起来)。 在数据表中搜索带有fldKey的,以输入字母开头的记录; 如果找到一个或多个记录,请将当前单元格(在屏幕上突出显示)移动到第一行。 如果未找到任何记录,请发出哔声并忽略该字符。 如果输入了Backspace,请从搜索字符串中删除最后一个字符,并找到缩短的搜索字符串的第一条匹配记录(如果没有剩余的搜索字符串,请移至第一条记录)。 如果用户通过向上和向下箭头,Page Up / Page Down或用鼠标单击来移动,则放弃搜索字符串并识别出该移动。

This can't really be made into a generalized class. You will need to use the code shown and customize it for your particular situation. In particular, the following objects need to be properly renamed for your code:

这真的不能做成广义类。 您将需要使用显示的代码并针对您的特定情况对其进行自定义。 特别是,以下对象需要为您的代码正确重命名:

dgv - the DataGridView

dgv-DataGridView

ds - the strongly typed DataSet that contains the DataTable dt

ds-包含DataTable dt的强类型DataSet

dsA - an instance of DataSet ds

dsA-DataSet ds的实例

dt - the DataTable of dsA which is the underlying source of data

dt-dsA的DataTable,它是基础数据源

dv - a DataView which is dgv's DataSource

dv-一个DataView,它是dgv的DataSource

fldKey - the field/column in DataTable dt on which to search; dgv needs to be sorted on this field

fldKey-要搜索的DataTable dt中的字段/列; dgv需要在此字段上排序

lblSearch - A label saying "Searching for:"

lblSearch-标签为“正在搜索:”

lblSearchDisplay - A label displaying the search string (without brackets on any punctuation)

lblSearchDisplay-显示搜索字符串的标签(任何标点符号都没有括号)

This code is written for Visual Basic/Visual Studio 2005 or later. For VB 2002/2003, DataGrid (instead of DataGridView) operations are essentially the same for this purpose. I believe the only change needed is to replace

此代码是为Visual Basic / Visual Studio 2005或更高版本编写的。 对于VB 2002/2003,为此目的,DataGrid(而不是DataGridView)操作基本上是相同的。 我相信唯一需要的改变就是更换

My.Computer.Audio.PlaySystemSound(Media.SystemSounds.Beep)

我的电脑音频播放系统 emSound(我 直径系统 声音蜜蜂 p)

with

Microsoft.VisualBasic.Beep

Microsoft.VisualBasic.Beep

which probably won't sound quite the same. (To play a .wav file, see the VS documentation for "sounds, playing example.")

听起来可能不太一样。 (要播放.wav文件,请参阅VS文档中的“声音,播放示例”。)

Public Class frm
    Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "
    ' This is omitted, because it'll be created when you set up the form
#End Region

    Private strSearch As String                         ' Search string, if typing in a lease number
    Private dv As DataView
    Private blnBackSpace As Boolean                     ' User typed a backspace to shorten search string

    Private Sub frm_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
        dv = dsA.dt.DefaultView
        dv.Sort = "fldKey"
        dgv.DataSource = dv
        dgv.Select()
	ClearSearch()
        blnBackSpace = False
    End Sub

    Private Sub dgv_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles dgv.KeyDown
        ' This event handler works with dgv_KeyPress to provide a progressive search in the DataGridView based on
        ' fldKey. This event handler responds to Backspace, up & down arrow, and Page Up/Page Down, which
        ' cannot be processed by the KeyPress event.
        Dim intSearch As Integer
        Select Case e.KeyCode
            Case Keys.Back
                If Len(strSearch) = 0 Then
                    My.Computer.Audio.PlaySystemSound(Media.SystemSounds.Beep)  ' Play error bell
                Else
                    ' If character deleted was an escaped special character, remove the brackets as well
                    If Mid(strSearch, Len(strSearch)) = "]" Then
                        strSearch = Mid(strSearch, 1, Len(strSearch) - 3)
                    Else
                        strSearch = Mid(strSearch, 1, Len(strSearch) - 1)
                    End If
                    If Len(strSearch) = 0 Then
                        intSearch = 0
                        ClearSearch()
                    Else
                        ' Find what's the first row that matches the new search string. We know there will be a match,
                        ' because this is a wider search than what's currently active.
        		intSearch = FindMatch()
                        lblSearchText.Text = Mid(lblSearchText.Text, 1, Len(lblSearchText.Text) - 1)
                    End If
                    dgv.CurrentCell = dgv.Item(0, intSearch)		' *** This assumes fldKey is the first column of the row
                End If
                blnBackSpace = True
            Case Keys.Down, Keys.Up, Keys.PageDown, Keys.PageUp
                ' If we use one of these keys, cancel the search process
                ClearSearch()
        End Select
    End Sub

    Private Sub dgv_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles dgv.KeyPress
        ' Progressive search for lease number. Add each character typed to the search string and look for a match
        ' The current search string is displayed in lblSearchDisplay.
        Dim intSearch As Integer
        If blnBackSpace = True Then                                     ' Backspace is handled by KeyDown, but Handled property
            e.Handled = True                                            '  has to be set here 
            blnBackSpace = False
            Return
        End If
        Dim strSaveSearch As String = strSearch                         ' Save in case of error
        ' Add newly typed character to list. If it's a special character, we need to surround with brackets
        ' or it'll be treated as a wildcard or some other special meaning.
        strSearch &= CStr(IIf(InStr("~()#\/=><+-*%&|^'""[]", e.KeyChar) > 0, "[" & e.KeyChar & "]", e.KeyChar))
        intSearch = FindMatch()                                         ' Look for a match
        If intSearch = -1 Then                                          ' No match
            My.Computer.Audio.PlaySystemSound(Media.SystemSounds.Beep)  ' Play bell
            strSearch = strSaveSearch                                   ' Revert to prior search string
        Else
            dgv.CurrentCell = dgv.Item(0, intSearch)		' *** This assumes fldKey is the first column of the row
            lblSearch.Visible = True
            lblSearchText.Visible = True
            lblSearchText.Text &= e.KeyChar
        End If
    End Sub

    Private Sub dgv_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles dgv.MouseClick
        ' If user clicks on a row, cancel the search process. 
        ClearSearch()
    End Sub

    Private Sub ClearSearch()
        lblSearch.Visible = False
        lblSearchText.Visible = False
        lblSearchText.Text = ""
        strSearch = ""
    End Sub

    Private Function FindMatch() As Integer
        Dim drFind() As ds.dtRow
        drFind = CType(dsA.dt.Select("fldKey LIKE '" & strSearch & "*'", "fldKey ASC"), ds.dtRow())
        If drFind.Count = 0 Then
            Return -1
        Else
            Return dv.Find(drFind(0).fldKey)
        End If
    End Function

End Class

翻译自: https://www.experts-exchange.com/articles/2210/Progressive-search-in-DataGridView.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值