网上也有很多类似文章,我是总结他们的,再加以革新绝对原创的。网上关于VB.NET的代码实在是太少了。虽然C#和VB.net大部分代码都通用稍作修改即可。
废话不说了贴代码
DataGridComboBox.Designer.vb
Partial Class DataGridComboBox
Inherits System.Windows.Forms.ComboBox
Public Sub New(ByVal container As System.ComponentModel.IContainer)
MyClass.New()
'Windows.Forms 类撰写设计器支持所必需的
If (container IsNot Nothing) Then
container.Add(Me)
End If
End Sub
'Component 重写 Dispose,以清理组件列表。
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
'组件设计器所必需的
Private components As System.ComponentModel.IContainer
'注意: 以下过程是组件设计器所必需的
'可使用组件设计器修改它。
'不要使用代码编辑器修改它。
Private Sub InitializeComponent()
Me.components = New System.ComponentModel.Container()
Me.ContextMenuStrip1 = New System.Windows.Forms.ContextMenuStrip(Me.components)
Me.编辑ToolStripMenuItem = New System.Windows.Forms.ToolStripMenuItem()
Me.ContextMenuStrip1.SuspendLayout()
Me.SuspendLayout()
'
'ContextMenuStrip1
'
Me.ContextMenuStrip1.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.编辑ToolStripMenuItem})
Me.ContextMenuStrip1.Name = "ContextMenuStrip1"
Me.ContextMenuStrip1.Size = New System.Drawing.Size(196, 26)
'
'编辑ToolStripMenuItem
'
Me.编辑ToolStripMenuItem.Name = "编辑ToolStripMenuItem"
Me.编辑ToolStripMenuItem.Size = New System.Drawing.Size(195, 22)
Me.编辑ToolStripMenuItem.Text = "ToolStripMenuItem1"
Me.ContextMenuStrip1.ResumeLayout(False)
Me.ResumeLayout(False)
End Sub
Friend WithEvents ContextMenuStrip1 As System.Windows.Forms.ContextMenuStrip
Friend WithEvents 编辑ToolStripMenuItem As System.Windows.Forms.ToolStripMenuItem
End Class
学vb.net的应该知道以上代码应该放在哪里(VS2010)
DataGridComboBox.vb 以下为程序区
Public Class DataGridComboBox
#Region "Class Data"
Private Const WM_LBUTTONDOWN As UInt32 = &H201
Private Const WM_LBUTTONDBLCLK As UInt32 = &H203
Private Const WM_KEYF4 As UInt32 = &H134
Private Const WM_CTLCOLORLISTBOX As UInt32 = &H134
Private WithEvents Grid As MyDataGrid
Private tsDD As ToolStripDropDown
Dim GridViewHost As ToolStripControlHost
#End Region
Public Sub New()
MyBase.New()
'组件设计器需要此调用。
InitializeComponent()
tsDD = New ToolStripDropDown()
Grid = New MyDataGrid
Grid.Width = 0
Grid.Height = 0
Grid.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.ColumnHeader
GridViewHost = New ToolStripControlHost(Grid)
tsDD.AutoSize = True
GridViewHost.AutoSize = False
Me.ContextMenuStrip = ContextMenuStrip1
End Sub
Dim mSourceTable As DataTable
Overloads Property DataSource As DataTable
Get
Return mSourceTable
'Return Grid.SourceTable
End Get
Set(ByVal value As DataTable)
mSourceTable = value
Grid.Columns.Clear()
If mSourceTable Is Nothing Then Return
Dim ColLent As Integer
For Each Col As DataColumn In mSourceTable.Columns
Grid.Columns.Add(Col.ColumnName, Col.ColumnName)
Grid.Columns(Col.ColumnName).DataPropertyName = Col.ColumnName
ColLent += Grid.Columns(Col.ColumnName).Width
Next
For Each Row As DataRow In mSourceTable.Rows
Dim GridRow As DataGridViewRow
Dim n As Integer = Grid.Rows.Add()
GridRow = Grid.Rows(n)
For Each Col As DataGridViewColumn In Grid.Columns
GridRow.Cells(Col.Name).Value = Row(Col.Name)
Next
Next
GridViewHost.Width = ColLent + Grid.RowHeadersWidth
GridViewHost.Height = CInt((Me.Font.Height + 3) * 8)
End Set
End Property
#Region "Methods"
Private Function CalculatePoz() As Point
Dim point As New Point(0, Me.Height)
If (Me.PointToScreen(New Point(0, 0)).Y + Me.Height + Me.Grid.Height) > Screen.PrimaryScreen.WorkingArea.Height Then
point.Y = -Me.Grid.Height - 7
End If
Return point
End Function
#End Region
Protected Overrides Sub WndProc(ByRef m As Message)
'#Region "WM_KEYF4"
If m.Msg = WM_KEYF4 Then
Me.Focus()
Me.tsDD.Refresh()
If Not Me.tsDD.Visible Then
If mSourceTable Is Nothing Then Return
tsDD.Items.Add(GridViewHost)
tsDD.Show(Me, Me.CalculatePoz())
End If
Return
End If
'#End Region
'#Region "WM_LBUTTONDBLCLK"
If m.Msg = WM_LBUTTONDBLCLK OrElse m.Msg = WM_LBUTTONDOWN Then
If Not Me.tsDD.Visible Then
If mSourceTable Is Nothing Then Return
tsDD.Items.Add(GridViewHost)
tsDD.Show(Me, Me.CalculatePoz())
End If
Return
End If
'#End Region
MyBase.WndProc(m)
End Sub
Private Sub Grid_CellMouseEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles Grid.CellMouseEnter
If e.RowIndex < 0 Or e.ColumnIndex < 0 Then Return
'BindingControlToToolTip(Grid, Grid.Rows(e.RowIndex).Cells(e.ColumnIndex).Value)’这个是绑定气泡提示的代码,可以不用的。
End Sub
Private Sub Grid_DoubleClick(ByVal sender As DataGridView, ByVal e As System.EventArgs) Handles Grid.DoubleClick
Dim Row As DataGridViewRow = sender.CurrentRow
Me.Text = ""
If Row IsNot Nothing Then
For Each Cell As DataGridViewCell In Row.Cells
If Me.Text.Trim.Length = 0 Then
Me.Text = Cell.Value.ToString
Else
Me.Text = Me.Text & "->" & Cell.Value.ToString
End If
Next
BindingControlToToolTip(Me, Me.Text)
End If
Me.tsDD.Close()
End Sub
‘这里是我的编辑区,可以按照自己的需求修改这里
Private Sub 编辑ToolStripMenuItem_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles 编辑ToolStripMenuItem.Click
Dim Frm As New Frm表格项目设定(mSourceTable)
Frm.ShowDialog()
End Sub
End Class
这里就算完成了,放到自己的程序 可以直接使用此控件.
有这个可举一反三了,可以把ComboBox跟更多的控件组合起来使用,这个程序里其实我也有纳闷的地方,比如直接DataGridView控件直接赋予DataSource一个DataTable显示出来的时候什么也没有,最后我不得不自己把数据取出来放到DataGridView控件里去,而不是采用数据绑定的方式。如果哪位仁兄能解决这个疑惑希望可以告知与我,谢谢。希望此段代码对新手有些帮助。网上很多代码不尽如人意。也有类似控件但是有缺陷。不能在窗体之外显示,受到TopLevelControl的限制。这里弹出的位置只和屏幕有关,所以就方便许多了。
这里包含了其他控件http://download.csdn.net/detail/earnmoney08/6935749(TreeView和ComboBox的组合以及加强版的TreeView)