最近在用VB.Net开发一个小程序时候,用到一个显示多列的ComboBox,而且从数据库中取出来的数据表要绑定到一个ComboBox中。找来找去,找不到。上Baidu Google很多人说:在VB.Net中的ComboBox只能绑定一列数据。以前的VBA和VB的ComBox可以显示多列数据的。上.Net的怎么不可以能。自己考虑到可以用一个ComboBox和一个ListView结合做一个能够显示多列内容的ComboBox下拉框,可以将一个数据表绑定到ComboBox中的用户控件。
自己就开始做,反复测试,改代码。
用户控件名:CmbBoxListView
控件里面有一个ComboBox和一个ListView。名称分别为:CmbBox和Lv。
控件的属性:
LvWidth 设置CmbBox中的List的宽度。
LvHeight 设置CmbBox中的List的高度。
IsShowColumnHeader 是否显示列标题。
IsShowRowHeader 是否显示行标题。
Text 获取或设置CmbBoxListView中的当前文本(重写基类Text)。
SelectedIndex 选中项的索引
控件的方法:(一个绑定数据表的方法,重载四次。)
BindDataTB(ByVal DataTB As DataTable, ByVal TBKeyWordName As String)
将DataTable的数据绑定到ListView中,作为CmbBox的List数据。并指定绑定的字段的名称。
BindDataTB(ByVal DataTB As DataTable, ByVal TBKeyWordPosition As Integer)
将DataTable的数据绑定到ListView中,作为CmbBox的List数据。并指定绑定的字段的位置。
BindDataTB(ByVal DataTB As DataTable, ByVal NewColumnsNameStr As String, ByVal KeyWordName As String)
将DataTable的数据绑定到ListView中,作为CmbBox的List数据。并指定新的列表标题和绑定的标题的名称。新的列表标题,用 , 或 ; 分隔开的字符串。
BindDataTB(ByVal DataTB As DataTable, ByVal NewColumnsNameStr As String, ByVal KeyWordPosition As Integer)
将DataTable的数据绑定到ListView中,作为CmbBox的List数据。并指定新的列表标题和绑定的标题的位置。新的列表标题,用 , 或 ; 分隔开的字符串。
使用起来很方便:
Me.CmbBoxListView1.LvWidth = 200
Me.CmbBoxListView1.LvHeight = 100
Me.CmbBoxListView1.IsShowColumnHeader = True
Me.CmbBoxListView1.IsShowRowHeader = False
Me.CmbBoxListView1.BindDataTB(Me.ADataSet.Dt, "你的;我的;他的;美的;好的", 1)
Me.TextBox1.Text = Me.CmbBoxListView1.Text
其中DataSet.Dt是一个DataSe的一个表Dt,表有5个字段名,绑定第一列为有效数据也就是控件CmbBoxListView中的当前文本Text属性。
------补充开始------
控件的下载地址:
http://download.csdn.net/source/954311
增加的一个事件,事件的使用和说明见:
http://blog.csdn.net/linjimu/archive/2009/01/09/3739537.aspx
------补充结束------
绑定效果:
整个控件的代码(已经添加了事件了):
- Public Class CmbBoxListView
- Inherits UserControl
- Public Delegate Sub ChangedTextEvent(ByVal sender As Object, ByVal e As EventArgs)
- Public Event SelectTextChanged As ChangedTextEvent
- Const CtrlHeight As Integer = 20
- Dim NewWidth, NewHeight, DesignCmbWidth As Integer
- Dim _TBKeyWordIndex As Integer
- Dim _IsShowColumnHeader As Boolean = True
- Dim _IsShowRowHeader As Boolean = True
- Dim _CmbBoxDorpDown As Boolean = False
-
-
-
-
-
-
- Public Property LvWidth() As Integer
- Get
- Return Me.Lv.Width
- End Get
- Set(ByVal Value As Integer)
- Me.Lv.Width = Value
- End Set
- End Property
-
-
-
-
-
-
- Public Property LvHeight() As Integer
- Get
- Return Me.Lv.Height
- End Get
- Set(ByVal Value As Integer)
- Me.Lv.Height = Value
- NewHeight = CtrlHeight + Value
- End Set
- End Property
-
-
-
-
-
-
- Public Property IsShowColumnHeader() As Boolean
- Get
- Return _IsShowColumnHeader
- End Get
- Set(ByVal Value As Boolean)
- _IsShowColumnHeader = Value
- End Set
- End Property
-
-
-
-
-
-
- Public Property IsShowRowHeader() As Boolean
- Get
- Return _IsShowRowHeader
- End Get
- Set(ByVal Value As Boolean)
- _IsShowRowHeader = Value
- End Set
- End Property
-
-
-
-
-
-
- Public Overrides Property Text() As String
- Get
- Return (Me.CmbBox.Text)
- End Get
- Set(ByVal Value As String)
- Me.CmbBox.Text = Value
- End Set
- End Property
- Public ReadOnly Property SelectedIndex() As Integer
- Get
- Return Lv.SelectedIndices.Item(0)
- End Get
- End Property
- Private Sub CmbBoxListView_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
- Me.Lv.Location = New Point(Me.CmbBox.Location.X, Me.CmbBox.Location.Y + Me.CmbBox.Height)
- Lv.GridLines = True
- Lv.FullRowSelect = True
- Lv.View = View.Details
- Lv.Scrollable = True
- Lv.MultiSelect = False
- Me.Lv.Clear()
- NewHeight = CtrlHeight + Me.Lv.Height
- End Sub
- Private Sub CmbBoxListView_SizeChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.SizeChanged
- If Me.Width < 40 Then
- Me.Width = 40
- End If
- If _CmbBoxDorpDown = False Then
- Me.Height = CtrlHeight
- DesignCmbWidth = Me.Width
- Me.CmbBox.Width = DesignCmbWidth
- End If
- End Sub
- Private Sub CmbBoxListView_LostFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.LostFocus
- Me.HidenLV()
- End Sub
- Private Sub CmbBox_DropDown(ByVal sender As Object, ByVal e As System.EventArgs) Handles CmbBox.DropDown
- Me.Lv.Visible = Not Me.Lv.Visible
- If Me.Lv.Visible = True Then
- _CmbBoxDorpDown = True
- If Me.CmbBox.Width > Me.Lv.Width Then
- Me.Lv.Width = Me.CmbBox.Width
- End If
- NewWidth = IIf(Me.Lv.Width > Me.CmbBox.Width, Me.Lv.Width, Me.CmbBox.Width)
- Me.Width = NewWidth
- Me.Height = NewHeight
- Me.BringToFront()
- Me.Lv.Select()
- Else
- _CmbBoxDorpDown = False
- Me.Width = DesignCmbWidth
- Me.Height = CtrlHeight
- End If
- End Sub
- Private Sub Lv_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Lv.Click
- Me.CmbBox.Text = Me.Lv.SelectedItems(0).SubItems(_TBKeyWordIndex + 1).Text
- RaiseEvent SelectTextChanged(Me, e)
- Me.HidenLV()
- End Sub
- Private Sub Lv_LostFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles Lv.LostFocus
- Me.HidenLV()
- End Sub
-
-
-
-
-
-
- Public Sub BindDataTB(ByVal DataTB As DataTable, ByVal TBKeyWordName As String)
- AddColumnsHeader(DataTB)
- FindKeyWordPosition(DataTB, TBKeyWordName)
- FillDataTB2Lv(DataTB)
- End Sub
-
-
-
-
-
-
- Public Sub BindDataTB(ByVal DataTB As DataTable, ByVal TBKeyWordPosition As Integer)
- AddColumnsHeader(DataTB)
- _TBKeyWordIndex = TBKeyWordPosition - 1
- FillDataTB2Lv(DataTB)
- End Sub
-
-
-
-
-
-
-
- Public Sub BindDataTB(ByVal DataTB As DataTable, ByVal NewColumnsNameStr As String, ByVal KeyWordName As String)
- AddColumnsHeader(NewColumnsNameStr)
- FindKeyWordPosition(NewColumnsNameStr, KeyWordName)
- FillDataTB2Lv(DataTB)
- End Sub
-
-
-
-
-
-
-
- Public Sub BindDataTB(ByVal DataTB As DataTable, ByVal NewColumnsNameStr As String, ByVal KeyWordPosition As Integer)
- AddColumnsHeader(NewColumnsNameStr)
- _TBKeyWordIndex = KeyWordPosition - 1
- FillDataTB2Lv(DataTB)
- End Sub
- Private Sub FillDataTB2Lv(ByVal _DataTB As DataTable)
- Dim i, j As Integer
- If _DataTB.Rows.Count > 0 Then
- Lv.Items.Clear()
- For i = 0 To _DataTB.Rows.Count - 1
- Dim li As New ListViewItem
- li.SubItems.Clear()
- li.Text = i
- For j = 0 To _DataTB.Columns.Count - 1
- li.SubItems.Add(_DataTB.Rows(i)(j).ToString)
- Next
- Lv.Items.Add(li)
- Next
- End If
- UpdateLvColRowSetting()
- End Sub
- Private Sub AddColumnsHeader(ByVal _DataTB As DataTable)
- Dim i As Integer
- If _DataTB.Rows.Count > 0 Then
- Lv.Columns.Clear()
- Lv.Columns.Add("序")
- Lv.Columns(0).Width = 30
- For i = 0 To _DataTB.Columns.Count - 1
- Lv.Columns.Add(_DataTB.Columns(i).Caption)
- Next
- End If
- End Sub
- Private Sub AddColumnsHeader(ByVal ColumnsNameStr As String)
- Dim i As Integer
- If ColumnsNameStr > "" Then
- Dim CName() As String
- Lv.Columns.Clear()
- Lv.Columns.Add("序")
- Lv.Columns(0).Width = 30
- If ColumnsNameStr.Contains(",") Then
- CName = Split(ColumnsNameStr, ",")
- For i = 0 To UBound(CName)
- Lv.Columns.Add(CName(i))
- Next
- End If
- If ColumnsNameStr.Contains(";") Then
- CName = Split(ColumnsNameStr, ";")
- For i = 0 To UBound(CName)
- Lv.Columns.Add(CName(i))
- Next
- End If
- End If
- End Sub
- Private Sub FindKeyWordPosition(ByVal _DataTB As DataTable, ByVal KeyWord As String)
- Dim i As Integer
- Dim TitleStr As ArrayList
- If _DataTB.Rows.Count > 0 Then
- TitleStr = New ArrayList
- For i = 0 To _DataTB.Columns.Count - 1
- TitleStr.Add(_DataTB.Columns(i).Caption)
- Next
- _TBKeyWordIndex = TitleStr.IndexOf(KeyWord)
- TitleStr = Nothing
- End If
- End Sub
- Private Sub FindKeyWordPosition(ByVal NewColumnsNameStr As String, ByVal KeyWord As String)
- Dim i As Integer
- Dim TitleStr As ArrayList
- If NewColumnsNameStr > "" Then
- Dim CName() As String
- TitleStr = New ArrayList
- If NewColumnsNameStr.Contains(",") Then
- CName = Split(NewColumnsNameStr, ",")
- For i = 0 To UBound(CName)
- TitleStr.Add(CName(i))
- Next
- _TBKeyWordIndex = TitleStr.IndexOf(KeyWord)
- End If
- If NewColumnsNameStr.Contains(";") Then
- CName = Split(NewColumnsNameStr, ",")
- For i = 0 To UBound(CName)
- TitleStr.Add(CName(i))
- Next
- _TBKeyWordIndex = TitleStr.IndexOf(KeyWord)
- End If
- TitleStr = Nothing
- End If
- End Sub
- Private Sub UpdateLvColRowSetting()
- If IsShowColumnHeader Then
- Lv.HeaderStyle = ColumnHeaderStyle.Nonclickable
- Else
- Lv.HeaderStyle = ColumnHeaderStyle.None
- End If
- If Lv.Columns.Count > 0 Then
- For i As Integer = 0 To (Lv.Columns.Count - 1)
- Lv.Columns(i).AutoResize(ColumnHeaderAutoResizeStyle.HeaderSize)
- Next
- End If
- If IsShowRowHeader Then
- If Lv.Columns.Count > 0 Then Lv.Columns(0).Width = 30
- Else
- If Lv.Columns.Count > 0 Then Lv.Columns(0).Width = 0
- End If
- End Sub
- Private Sub HidenLV()
- Me.Lv.Visible = False
- Me.Width = DesignCmbWidth
- Me.Height = CtrlHeight
- End Sub
- End Class