积极答复者
如何将ComboBox下拉列表视图滚动到某项?

问题
答案
-
我明白了——你的意思是:使用SelectedItem自动滚屏到选中项,使其成为第一项,然后可以继续输入,参考一下代码,尤其是重要部分:
Imports System.ComponentModel
<ToolboxBitmap(GetType(ComboBox), "ComboBox.bmp")> Public Class HComboBox
Inherits ComboBox
Private backup As String = Nothing
Public Sub New()
MyBase.New()
Me.SelectedValue = 0
End Sub
Protected Overrides Sub OnKeyUp(ByVal e As System.Windows.Forms.KeyEventArgs)
If Me.Items.Count > 0 Then
Dim query = From row In Me.Items.Cast(Of String)() Where GetHzPy(row) Like Me.Text.Trim & "*" OrElse row Like Me.Text.Trim & "*"
If query.Count > 0 Then
backup = Me.Text
Me.SelectedItem = query.FirstOrDefault
Me.Text = backup
Me.SelectionStart = Me.Text.Length '注意:从1开始索引!
Else
Beep()
End If
End If
e.Handled = True
End Sub
Public Shared Function GetHzPy(ByVal cnChar As String) As String
Dim hzpy As String = "", s As String
Dim arrCN As Byte()
Dim area As Integer
Dim pos As Integer
Dim code As Integer
Dim areacode As Integer() = {45217, 45253, 45761, 46318, 46826, 47010, 47297, 47614, 48119, 48119, 49062, 49324, 49896, 50371, 50614, 50622, 50906, 51387, 51446, 52218, 52698, 52698, 52698, 52980, 53689, 54481}
For i As Integer = 1 To cnChar.Length
s = Mid(cnChar, i, 1)
arrCN = System.Text.Encoding.[Default].GetBytes(s)
If arrCN.Length > 1 Then
area = CShort(arrCN(0))
pos = CShort(arrCN(1))
code = (area << 8) + pos
For j As Integer = 0 To 25
Dim max As Integer = 55290
If j <> 25 Then max = areacode(j + 1)
If areacode(i) <= code AndAlso code < max Then
s = System.Text.Encoding.[Default].GetString(New Byte() {CByte((65 + j))})
Exit For
End If
Next
End If
hzpy &= s
Next
Return hzpy
End Function
End Class
QQ我:
下载MSDN桌面工具(Vista,Win7)
我的博客园
慈善点击,点击此处
- 已编辑 ThankfulHeartModerator 2012年1月9日 3:44
- 已标记为答案 大海怪 2012年1月10日 0:49
全部回复
-
你好:)
1)你说下拉列表在Dropdown样式下会自动搜索输入项,对不起,我这里无法重现你的情况,无法实现自动搜索,请仔细看看你还有没有设置其它属性(比如AutoCompleteSource什么的)。
2)我没有明白你的意思——只能搜索项的显示部分,请具体配合代码和截图说明。
3)你自己的方法又是什么?是模糊搜索吗?看你的截图不就已经实现了效果么?
附加说明:点击我签名部分,直接可以把邮件连同项目发给我,我看看(尽量不要数据库)
QQ我:
下载MSDN桌面工具(Vista,Win7)
我的博客园
慈善点击,点击此处
- 已编辑 ThankfulHeartModerator 2012年1月8日 4:59
-
谢谢回复!
主要设置如下:
With Me.ComboBox
.DropDownStyle = ComboBoxStyle.DropDown
.DataSource = Me.BindingSource
.DisplayMember = "mc"
.ValueMember = "bh"End With
运行时,点击下拉箭头,显示列表,然后在文本框中输入字符,列表会随着输入,渐进式搜索"mc"开头与文本框中匹配的项,如下(提问中的图也是控件本身的默认执行效果):
但该控件只能搜索DisplayMember 的内容,若想搜索ValueMember 或其它列的内容,则必须自己写方法(这个在KeyUp事件中很容易实现,问题是搜索到后怎么处理,才能既让它出现在列表的的最顶端,而又不让它出现在文本框中)
韩立学 -
你的意思是不是在文本框中输入内容,针对DisplayName和ValueName一同搜索,然后按照DisplayName显示出来?
比如:
那么当输入“1”的时候,应该出现“产品2”(因为它的对应Value是1),同时出现“产品11”(DisplayName中包含1)。是这样吗?
QQ我:
下载MSDN桌面工具(Vista,Win7)
我的博客园
慈善点击,点击此处
- 已编辑 ThankfulHeartModerator 2012年1月8日 7:04
-
你的意思是不是在文本框中输入内容,针对DisplayName和ValueName一同搜索,然后按照DisplayName显示出来?
比如:
那么当输入“1”的时候,应该出现“产品2”(因为它的对应Value是1),同时出现“产品11”(DisplayName中包含1)。是这样吗?
QQ我:
下载MSDN桌面工具(Vista,Win7)
我的博客园
慈善点击,点击此处
不是这个意思,是搜索到后怎么处理,才能既让它符合条件的第一项出现在列表的的最顶端,而又不让它出现在文本框中(否则,会影响继续输入)。我用的是:Me.SelectedItem = 找到的项,这样处理,该项能够出现在列表的最顶端,但同时,它的值也出现在了文本框中,要避免的后者。
比如:输入123,这时若第一个符合条件的项是:123001,那么,文本框会变成123001,这给继续查找带来了不便,如果要继续查找1234.....,则不能接着输入,必须删除001 。就是要求,在用户最终找到所要的项之前,文本框中的内容始终是用户输入的内容,而不是项的内容。说到底,就是要扩展一下原控件的查找范围(不仅仅局限于DisplayMember),但执行效果不变(即用户每输入一个字符,符合条件的项便出现在列表的最顶端,但文本框始终显示用户输入的字符,直到最终找到需要的项为止)
韩立学
- 已编辑 大海怪 2012年1月8日 7:52
-
我明白了——你的意思是:使用SelectedItem自动滚屏到选中项,使其成为第一项,然后可以继续输入,参考一下代码,尤其是重要部分:
Imports System.ComponentModel
<ToolboxBitmap(GetType(ComboBox), "ComboBox.bmp")> Public Class HComboBox
Inherits ComboBox
Private backup As String = Nothing
Public Sub New()
MyBase.New()
Me.SelectedValue = 0
End Sub
Protected Overrides Sub OnKeyUp(ByVal e As System.Windows.Forms.KeyEventArgs)
If Me.Items.Count > 0 Then
Dim query = From row In Me.Items.Cast(Of String)() Where GetHzPy(row) Like Me.Text.Trim & "*" OrElse row Like Me.Text.Trim & "*"
If query.Count > 0 Then
backup = Me.Text
Me.SelectedItem = query.FirstOrDefault
Me.Text = backup
Me.SelectionStart = Me.Text.Length '注意:从1开始索引!
Else
Beep()
End If
End If
e.Handled = True
End Sub
Public Shared Function GetHzPy(ByVal cnChar As String) As String
Dim hzpy As String = "", s As String
Dim arrCN As Byte()
Dim area As Integer
Dim pos As Integer
Dim code As Integer
Dim areacode As Integer() = {45217, 45253, 45761, 46318, 46826, 47010, 47297, 47614, 48119, 48119, 49062, 49324, 49896, 50371, 50614, 50622, 50906, 51387, 51446, 52218, 52698, 52698, 52698, 52980, 53689, 54481}
For i As Integer = 1 To cnChar.Length
s = Mid(cnChar, i, 1)
arrCN = System.Text.Encoding.[Default].GetBytes(s)
If arrCN.Length > 1 Then
area = CShort(arrCN(0))
pos = CShort(arrCN(1))
code = (area << 8) + pos
For j As Integer = 0 To 25
Dim max As Integer = 55290
If j <> 25 Then max = areacode(j + 1)
If areacode(i) <= code AndAlso code < max Then
s = System.Text.Encoding.[Default].GetString(New Byte() {CByte((65 + j))})
Exit For
End If
Next
End If
hzpy &= s
Next
Return hzpy
End Function
End Class
QQ我:
下载MSDN桌面工具(Vista,Win7)
我的博客园
慈善点击,点击此处
- 已编辑 ThankfulHeartModerator 2012年1月9日 3:44
- 已标记为答案 大海怪 2012年1月10日 0:49