如何在网格列(UltraWinGrid)中实现增量搜索
本文旨在展示如何通过双击 UltraWinGrid 列来实现增量搜索。
引言
此代码为您提供了一个问题的解决方案:如何在 WinGrid 列中双击实现增量搜索?也许编码存在一些不足,但我相信它会给您一个如何完成此过程的思路。
注释
此新版本包括一个用于清除筛选器/增量搜索文本框的按钮。之前的版本,当鼠标光标离开列时会清除/删除此元素。搜索功能已得到改进,冗余代码已删除,现在增量搜索框仅在鼠标光标位于列标题上时才添加。使用方法 ElementWithMouseCapture
进行代码优化。
当增量搜索或过滤数据的文本框放置在某一列上并进行滚动时,此文本框会覆盖单元格。此问题已在此版本中修复。
概览(背景)
使用 Infragistics.Win.UIElement
对象,您可以验证鼠标光标所在的界面对象的类型。此对象还具有 GetContext
方法,该方法返回对象的主 UI。如果您编写代码,您会发现此对象是 TextUIElement
。您还会看到 ColumnHeader
和 SortIndicatorUIElement
对象存在于对象列中。我检测光标所在的对象是否是列,并通过代码向其添加 UltraTextEditor
对象。此对象有一个用于过滤的按钮(只有当用户单击此按钮时才执行过滤),一个用于移除过滤的按钮,以及 TextChanged
事件中的代码用于增量搜索。由于在分组列特征启用时,网格的工作方式不同,因此也已考虑在内。如果您检查代码,您会发现它验证网格行是否属于某个组(使用 UltraGridGroupByRow
和 ChildBands
)。我编写的代码以两种方式工作:用户可以选择进行过滤或进行增量搜索(隐式)。
本文还展示了如何显示列上的工具提示以及如何将数据绑定到文本框以在记录之间导航。
代码概述
为了正确执行,需要以下命名空间。
Imports System.IO
Imports System.String
Imports System.Data
Imports System.Data.SqlClient
Imports Infragistics.Win.UltraWinGrid
Imports Infragistics.Win
Imports Infragistics.Shared
使用以下变量,并且必须声明。
#Region " V A R I A B L E S "
Dim bindman As BindingManagerBase 'For bind the text boxes to the row's grid.
'A local data set. You need modify the connection string
Dim localdataset As New System.Data.DataSet
Dim _activeColumn As String
Dim ui As Infragistics.Win.UIElement
Dim aColumnHeader As Infragistics.Win.UltraWinGrid.ColumnHeader
Dim nRowByGroupOriginal As Long
#End Region
在 Load
事件中,执行与 SQL 数据库的连接。您需要修改连接字符串以指向有效的数据库和表才能正确执行。网格具有 Outlook 样式视图。此事件的最后一行代码展示了如何向网格中的单元格添加图像,在本例中,是第一个单元格。
Private Sub Itemsforupdate_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Me.grdItems.DisplayLayout.ViewStyleBand = _
Infragistics.Win.UltraWinGrid.ViewStyleBand.OutlookGroupBy
Dim sqlAdapter As New SqlDataAdapter( _
"SELECT * FROM customers", _
New SqlConnection("Initial Catalog=northwind;Data Source= _
(local);Integrated Security=SSPI;"))
sqlAdapter.Fill(localdataset, "customers")
Me.UltraTextEditor1.DataBindings.Add("text", _
localdataset.Tables("customers"), "customerid")
Me.UltraTextEditor2.DataBindings.Add("text", _
localdataset.Tables("customers"), "contactname")
bindman = Me.BindingContext(localdataset.Tables("customers"))
Me.grdItems.DataSource = localdataset.Tables("customers")
Me.grdItems.Rows(0).Cells(0).Appearance.Image = _
System.Drawing.Image.FromFile(Application.StartupPath & "\clock.png")
End Sub
Paint
事件中的下一段代码为窗体设置了酷炫的填充。棒极了!
Private Sub Itemsforupdate_Paint(ByVal sender As Object, _
ByVal e As System.Windows.Forms.PaintEventArgs) _
Handles MyBase.Paint
Dim FillBrush As New Drawing2D.LinearGradientBrush(ClientRectangle, _
Color.Khaki, Color.WhiteSmoke, _
Drawing2D.LinearGradientMode.ForwardDiagonal)
e.Graphics.FillRectangle(FillBrush, ClientRectangle)
FillBrush.Dispose()
End Sub
在 MouseEnterElement
事件中,我检查鼠标光标所在的控件。这是必要的,因为增量文本框是添加到标题或列上的。此事件的第一行代码对 UI 元素进行类型转换,并将其转换为 ColumnHeader
元素(控件)。注释掉的代码允许在鼠标进入列标题时添加增量搜索的文本框。此事件展示了如何在每列上显示工具提示。当您有许多列且尺寸较小时,此功能非常有用。
以下代码已修订并更新!
Private Sub grdItems_MouseEnterElement(ByVal sender As Object, _
ByVal e As Infragistics.Win.UIElementEventArgs) _
Handles grdItems.MouseEnterElement
aColumnHeader = _
CType(e.Element.GetContext( _
GetType(Infragistics.Win.UltraWinGrid.ColumnHeader)), _
Infragistics.Win.UltraWinGrid.ColumnHeader)
If Not aColumnHeader Is Nothing And TypeOf e.Element Is HeaderUIElement Then
_activeColumn = aColumnHeader.Column.Key
MyToolTip.Active = True
MyToolTip.SetToolTip(CType(sender, System.Windows.Forms.Control), _
aColumnHeader.Column.Key)
MyTextSearchBox.Size = _
New Size(aColumnHeader.SizeResolved.Width, _
aColumnHeader.SizeResolved.Height)
ui = e.Element
aColumnHeader.Band.ColHeaderLines = 1
Exit Sub
End If
End Sub
MouseLeaveElement
事件中的代码会移除工具提示的文本。
以下代码已修订并更新!
Private Sub grdItems_MouseLeaveElement(ByVal sender As Object, _
ByVal e As Infragistics.Win.UIElementEventArgs) _
Handles grdItems.MouseLeaveElement
Dim ui As Infragistics.Win.UIElement
ui = e.Element
If TypeOf e.Element Is HeaderUIElement Then
MyToolTip.SetToolTip(sender, String.Empty)
End If
End Sub
过滤网格行的代码位于文本框控件的 EditorButtonClick
事件中。
以下代码已修订并更新!
Private Sub MyTextSearchBox_EditorButtonClick(ByVal sender As Object, _
ByVal e As Infragistics.Win.UltraWinEditors.EditorButtonEventArgs) _
Handles MyTextSearchBox.EditorButtonClick
Dim band As UltraGridBand = Me.grdItems.DisplayLayout.Bands(0)
Select Case e.Button.Key.ToLower
Case "clearfilter"
RemoveFilter()
Case Else
band.Override.AllowRowFiltering = DefaultableBoolean.True
band.Override.RowFilterMode = RowFilterMode.AllRowsInBand
band.ColumnFilters(_activeColumn).FilterConditions.Add( _
FilterComparisionOperator.Like, _
"*" & MyTextSearchBox.Text.Trim & "*")
End Select
End Sub
增量搜索的代码位于文本框控件的 TextChanged
事件中。当网格的行按列分组或具有子带(如 Outlook 样式)时,代码是不同的。
以下代码已修订和更改!
Private Sub MyTextSearchBox_TextChanged(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles MyTextSearchBox.TextChanged
If MyTextSearchBox.Text <> "" Then
Dim myCellValue As String
Static gRow As UltraGridRow
Dim nRow As Long
Me.grdItems.SuspendLayout()
grdItems.BeginUpdate()
Me.grdItems.DisplayLayout.Override.MaxSelectedCells = 1
Me.grdItems.DisplayLayout.Override.SelectTypeCell = SelectType.Single
If (Not TypeOf grdItems.ActiveRow Is _
Infragistics.Win.UltraWinGrid.UltraGridGroupByRow _
And IsNothing(grdItems.Rows(nRowByGroupOriginal).ChildBands)) Then
For Each gRow In Me.grdItems.Rows
grdItems.ActiveRow = gRow
myCellValue = grdItems.ActiveRow.Cells(_activeColumn).Text
If [String].CompareOrdinal(myCellValue.ToLower, _
LCase(Me.MyTextSearchBox.Text.Trim)) > 0 Then
gRow.Cells(_activeColumn).Activate()
gRow.Cells(_activeColumn).Selected = True
Exit For
End If
Next
Else
For Each gRow In grdItems.Rows(nRowByGroupOriginal).ChildBands(0).Rows
myCellValue = _
grdItems.Rows(nRowByGroupOriginal).ChildBands(0).Rows( _
gRow.Index).Cells(_activeColumn).Text
If [String].CompareOrdinal(myCellValue.ToLower, LCase( _
Me.MyTextSearchBox.Text.Trim)) > 0 Then
grdItems.Rows(nRowByGroupOriginal).ChildBands(0).Rows( _
gRow.Index).Cells(_activeColumn).Activate()
grdItems.Rows(nRowByGroupOriginal).ChildBands(0).Rows( _
gRow.Index).Cells(_activeColumn).Selected =_
True
Exit For
End If
Next
End If
Me.grdItems.ResumeLayout()
grdItems.EndUpdate()
End If
End Sub
以下代码用于强制网格滚动到第一行(当执行筛选或增量搜索时)。
Private Sub grdItems_BeforeRowActivate(ByVal sender As Object, _
ByVal e As Infragistics.Win.UltraWinGrid.RowEventArgs) _
Handles grdItems.BeforeRowActivate
' determine which row should be the top row
Dim rowTop As UltraGridRow
If e.Row.Band.Index = 0 Then
rowTop = e.Row
Else
rowTop = e.Row.ParentRow
End If
With grdItems.DisplayLayout
' scroll the row into the RowScrollRegion
.RowScrollRegions(0).ScrollRowIntoView(rowTop)
' turn off display refresh during update
grdItems.BeginUpdate()
' scroll the top row to the top
Do Until .RowScrollRegions(0).VisibleRows(0).Row Is rowTop
.RowScrollRegions(0).Scroll(RowScrollAction.LineDown)
Loop
' turn display refresh back on
grdItems.EndUpdate()
End With
End Sub
在 DoubleClick
事件中添加用于增量搜索的控件。当用户双击 columnheader
元素(边框)时,会添加文本框。主要上下文元素是 TextUIElement
,但当用户点击时,网格默认按列标题对列进行排序。因此,当用户点击 TextUIElement
时,我没有添加文本框。
以下代码已修订和更新!
Private Sub grdItems_DoubleClick(ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles grdItems.DoubleClick
If Not IsNothing(ui) Then
If _activeColumn <> "" And _
TypeOf ui.ControlElement.ElementWithMouseCapture Is HeaderUIElement Then
grdItems.DisplayLayout.Bands(0).Columns(_activeColumn).SortIndicator _
= SortIndicator.None
grdItems.PerformAction(UltraGridAction.FirstRowInBand)
' If Then
MyTextSearchBox.Location = ui.Rect.Location
ui.Control.Controls.Add(MyTextSearchBox)
MyTextSearchBox.Visible = True
MyTextSearchBox.Focus()
'End If
End If
End If
End Sub
当网格具有分组(如 Outlook 样式)时,以下代码至关重要。获取当前展开的组。
Private Sub grdItems_AfterRowExpanded(ByVal sender As Object, _
ByVal e As Infragistics.Win.UltraWinGrid.RowEventArgs) _
Handles grdItems.AfterRowExpanded
nRowByGroupOriginal = e.Row.Index
End Sub
为了移除过滤或增量搜索的文本框,我使用了 Sub RemoveFilter
。当用户点击 ClearFilter
按钮(第二个按钮)时,将调用此 S
ub
。
新增代码
Private Sub RemoveFilter()
Dim band As UltraGridBand = Me.grdItems.DisplayLayout.Bands(0)
band.Override.AllowRowFiltering = DefaultableBoolean.False
band.ColumnFilters(_activeColumn).FilterConditions.Clear()
MyToolTip.SetToolTip(ui.Control, String.Empty)
MyTextSearchBox.Visible = False
ui.Control.Controls.Clear()
_activeColumn = ""
End Sub
为避免增量搜索文本框放置在网格上的任何位置,我编写了这些新事件
Private Sub grdItems_BeforeRowRegionScroll(ByVal sender As Object, _
ByVal e As Infragistics.Win.UltraWinGrid.BeforeRowRegionScrollEventArgs) _
Handles grdItems.BeforeRowRegionScroll
grdItems.SuspendLayout()
If Not IsNothing(ui) Then
If TypeOf ui.ControlElement.LastElementEntered Is _
Infragistics.Win.UltraWinScrollBar.ScrollArrowUIElement Or _
TypeOf ui.ControlElement.ElementWithMouseCapture Is _
Infragistics.Win.UltraWinScrollBar.ScrollBarUIElement Then
ui.Control.Controls.Clear()
End If
End If
End Sub
Private Sub grdItems_BeforeColRegionScroll(ByVal sender As Object, _
ByVal e As Infragistics.Win.UltraWinGrid.BeforeColRegionScrollEventArgs) _
Handles grdItems.BeforeColRegionScroll
grdItems.SuspendLayout()
If Not IsNothing(ui) Then
If TypeOf ui.ControlElement.LastElementEntered Is _
Infragistics.Win.UltraWinScrollBar.ScrollArrowUIElement Or _
TypeOf ui.ControlElement.ElementWithMouseCapture Is _
Infragistics.Win.UltraWinScrollBar.ScrollBarUIElement Then
ui.Control.Controls.Clear()
End If
End If
End Sub
Private Sub grdItems_AfterColRegionScroll(ByVal sender As Object, _
ByVal e As Infragistics.Win.UltraWinGrid.ColScrollRegionEventArgs) _
Handles grdItems.AfterColRegionScroll
grdItems.ResumeLayout()
End Sub
Private Sub grdItems_AfterRowRegionScroll(ByVal sender As Object, _
ByVal e As Infragistics.Win.UltraWinGrid.RowScrollRegionEventArgs) _
Handles grdItems.AfterRowRegionScroll
grdItems.ResumeLayout()
End Sub
摘要
在此代码中,您可以看到(版本 2.0,2005/02/10,1652)
- 如何在运行时将控件添加到具有焦点(或鼠标悬停)的对象上。
- 如何为每列添加工具提示。
- 如何按特定列过滤行。
- 如何在列中的数据上进行增量搜索。
- 如何使用
CType()
、GetContext()
函数。 - 如何使用 SQL Server 2000 连接到数据库:
sqlConnection
、sqlDataAdapter
、DataSets
。 - 如何向特定单元格添加图像。
- 如何验证网格是否具有行组(如 Outlook 样式)。
- 如何滚动网格以使筛选条件或增量搜索的条件文本中指示的元素可见。
- 如何使用
filterconditions
过滤数据。 - 如何使用
CompareTo
函数比较两个字符串。 - 如何使用
Infragistics.Win.UIElement
检测特定控件或元素:HeaderUIElement
、SortIndicatorUIElement
、TextUIElement
、ElementWithMouseCapture
等。 - 如何对窗体应用
LinearGradient
填充,以获得炫酷效果。
版本 2.0
- 添加一个按钮以移除用于过滤或增量搜索的文本框。
- 实现列/行
ScrollRegion
之前的/之后的事件,以便在用户滚动时移除文本框。这可以避免控件在单元格上方“放置”(仅视觉上)。 - 改进了
DoubleClick
事件中的代码。使用ElementWithMouseCapture
,双击事件仅在ui.ControlElement
类型为HeaderUIElement
时执行。 - 使用
CompareOrdinal
方法而不是CompareTo
方法进行文本搜索。 - 修复了一个未处理的异常错误;当用户在窗体启动后立即滚动,而没有将鼠标光标移动到列上方时(未创建
ui
元素)。
Notice
此代码假定您正在使用 Infragistics UltraWinGrid,并且是此出色组件套件的授权用户。您可以从此处下载 NetAdvantage 2004 vol 3 的试用版。此代码仅用于演示目的。您还需要连接到 SQL Server 2000 Northwind 数据库。
我希望此代码对您有用。从此处下载 NetAdvantage 2004 Vol 3 的试用版。
此致,
CFQüeb