网上也有很多类似文章,我是总结他们的,再加以革新绝对原创的。网上关于VB.NET的代码实在是太少了。虽然C#和VB.net大部分代码都通用稍作修改即可。
废话不说了贴代码
DataGridComboBox.Designer.vb
Partial Class DataGridComboBox
Inherits System.Windows.Forms.ComboBox
<System.Diagnostics.DebuggerNonUserCode()> _
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,以清理组件列表。
<System.Diagnostics.DebuggerNonUserCode()> _
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
'注意: 以下过程是组件设计器所必需的
'可使用组件设计器修改它。
'不要使用代码编辑器修改它。
<System.Diagnostics.DebuggerStepThrough()> _
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)