RE:Introducir un ComboBox en un DataGrid
'Aqui hay 2 clases que tienes que crear, consus respectivos nombres, luego. Cambia la direccion de tu BD ya que este ejemplo abre una bd en access.
'Ejecuta y veras .....................................
''''''''''''Clase ComboSinKeyUp'''''''''''''''''''''''''''''''''''''''''''''
Public Class ComboSinKeyUp
Inherits ComboBox
Private WM_KEYUP As Integer = &H101
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If m.Msg = WM_KEYUP Then
'Ignora el keyup para evita problemas de tabulación
Return
End If
MyBase.WndProc(m)
End Sub
End Class
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''''''''''''Clase dataGridCombo''''''''''''''''''''''''''''''''''''''''''''''
Imports Microsoft.VisualBasic
Imports System
Imports System.ComponentModel
Imports System.Data
Imports System.Data.Common
Imports System.Data.OleDb
Imports System.Drawing
Imports System.Windows.Forms
'Paso 1. Derivar un estilo de columna a DataGridTextBoxColumn
' a) agregar un miembro a la ComboBox
' b) Detectar cuando la combobox tiene el foco en los eventos Enter y Leave
' c) Sobreescribir el Edit para permitir a la ComboBox remplazar la textbox de la Datagrid
' d) Sobreescribir el Commit para salvar los cambios de los datos
Public Class DataGridComboBoxColumn
Inherits DataGridTextBoxColumn
Public ColumnComboBox As ComboSinKeyUp 'Atención aquí con esta declaración
Private _Origen As System.Windows.Forms.CurrencyManager
Private _NroRenglon As Integer
Private _EstaEditando As Boolean
Public Shared _RowCount As Integer
Public Sub New()
_Origen = Nothing
_EstaEditando = False
_RowCount = -1
ColumnComboBox = New ComboSinKeyUp
ColumnComboBox.DropDownStyle = ComboBoxStyle.DropDownList
AddHandler ColumnComboBox.Leave, AddressOf DejaComboBox
AddHandler ColumnComboBox.SelectionChangeCommitted, AddressOf ComienzaEditarCombo
End Sub
Private Sub ManejaScroll(ByVal sender As Object, ByVal e As EventArgs)
If ColumnComboBox.Visible Then
ColumnComboBox.Hide()
End If
End Sub
Private Sub ComienzaEditarCombo(ByVal sender As Object, ByVal e As EventArgs)
_EstaEditando = True
MyBase.ColumnStartedEditing(sender)
End Sub
Private Sub DejaComboBox(ByVal sender As Object, ByVal e As EventArgs)
If _EstaEditando Then
SetColumnValueAtRow(_Origen, _NroRenglon, ColumnComboBox.Text)
_EstaEditando = False
Invalidate()
End If
ColumnComboBox.Hide()
AddHandler Me.DataGridTableStyle.DataGrid.Scroll, New EventHandler(AddressOf ManejaScroll)
End Sub
Protected Overloads Overrides Sub Edit(ByVal [source] As System.Windows.Forms.CurrencyManager, ByVal rowNum As Integer, ByVal bounds As System.Drawing.Rectangle, ByVal [readOnly] As Boolean, ByVal instantText As String, ByVal cellIsVisible As Boolean)
MyBase.Edit([source], rowNum, bounds, [readOnly], instantText, cellIsVisible)
_NroRenglon = rowNum
_Origen = [source]
ColumnComboBox.Parent = Me.TextBox.Parent
ColumnComboBox.Location = Me.TextBox.Location
ColumnComboBox.Size = New Size(Me.TextBox.Size.Width, ColumnComboBox.Size.Height)
ColumnComboBox.SelectedIndex = ColumnComboBox.FindStringExact(Me.TextBox.Text)
ColumnComboBox.Text = Me.TextBox.Text
Me.TextBox.Visible = False
ColumnComboBox.Visible = True
AddHandler Me.DataGridTableStyle.DataGrid.Scroll, AddressOf ManejaScroll
ColumnComboBox.BringToFront()
ColumnComboBox.Focus()
End Sub
Protected Overrides Function Commit(ByVal dataSource As System.Windows.Forms.CurrencyManager, ByVal rowNum As Integer) As Boolean
If _EstaEditando Then
_EstaEditando = False
SetColumnValueAtRow(dataSource, rowNum, ColumnComboBox.Text)
End If
Return True
End Function
Protected Overrides Sub ConcedeFocus()
MyBase.ConcedeFocus()
End Sub
Protected Overrides Function GetColumnValueAtRow(ByVal [source] As System.Windows.Forms.CurrencyManager, ByVal rowNum As Integer) As Object
Dim s As Object = MyBase.GetColumnValueAtRow([source], rowNum)
Dim dv As DataView = CType(Me.ColumnComboBox.DataSource, DataView)
Dim rowCount As Integer = dv.Count
Dim i As Integer = 0
Dim s1 As Object
While i < rowCount
s1 = dv(i)(Me.ColumnComboBox.ValueMember)
If (Not s1 Is DBNull.Value) AndAlso _
(Not s Is DBNull.Value) AndAlso _
s = s1 Then
Exit While
End If
i = i + 1
End While
If i < rowCount Then
Return dv(i)(Me.ColumnComboBox.DisplayMember)
End If
Return DBNull.Value
End Function
Protected Overrides Sub SetColumnValueAtRow(ByVal [source] As System.Windows.Forms.CurrencyManager, ByVal rowNum As Integer, ByVal value As Object)
Dim s As Object = value
Dim dv As DataView = CType(Me.ColumnComboBox.DataSource, DataView)
Dim rowCount As Integer = dv.Count
Dim i As Integer = 0
Dim s1 As Object
While i < rowCount
s1 = dv(i)(Me.ColumnComboBox.DisplayMember)
If (Not s1 Is DBNull.Value) AndAlso _
s = s1 Then
Exit While
End If
i = i + 1
End While
If i < rowCount Then
s = dv(i)(Me.ColumnComboBox.ValueMember)
Else
s = DBNull.Value
End If
MyBase.SetColumnValueAtRow([source], rowNum, s)
End Sub
End Class
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'''''''''''Esto va en tu Form'''''''''''''''''''''''''''''''''''''''''''''
Private miDataSet As DataSet
Private dataAdapter As OleDb.OleDbDataAdapter
Private Sub HacerDataSetYEnlazarGrid()
Dim connString As String = "Provider=Microsoft.JET.OLEDB.4.0;data source=C:\Documents and Settings\Laptop\Mis documentos\NORTHwind.MDB"
Dim sqlString As String = "SELECT * FROM Pedidos"
dataAdapter = Nothing
miDataSet = Nothing
Try
Dim connection As New OleDb.OleDbConnection(connString)
dataAdapter = New OleDb.OleDbDataAdapter(sqlString, connection)
miDataSet = New DataSet
dataAdapter.Fill(miDataSet, "Pedidos")
sqlString = "SELECT IDcliente, NombreContacto FROM Clientes"
dataAdapter = New OleDb.OleDbDataAdapter(sqlString, connection)
dataAdapter.Fill(miDataSet, "Lista de Clientes")
connection.Close()
Catch ex As Exception
MessageBox.Show(("Problema al acceder a la Base de datos" + ex.ToString()))
Me.Close()
Return
End Try
Dim tableStyle As New DataGridTableStyle
tableStyle.MappingName = "Pedidos"
'tableStyle.DataGrid = dataGrid1
Dim dt As DataTable = miDataSet.Tables("Pedidos")
Dim i As Integer
While i < dt.Columns.Count
If i <> 1 Then
Dim TextCol As New DataGridTextBoxColumn
TextCol.MappingName = dt.Columns(i).ColumnName
TextCol.HeaderText = dt.Columns(i).ColumnName
tableStyle.GridColumnStyles.Add(TextCol)
Else
Dim ComboTextCol As New DataGridComboBoxColumn
ComboTextCol.MappingName = "IDCliente"
ComboTextCol.HeaderText = "Cliente (Combo)"
ComboTextCol.Width = 120
ComboTextCol.ColumnComboBox.DataSource = miDataSet.Tables("Lista de Clientes").DefaultView
ComboTextCol.ColumnComboBox.DisplayMember = "NombreContacto"
ComboTextCol.ColumnComboBox.ValueMember = "IDCliente"
tableStyle.PreferredRowHeight = ComboTextCol.ColumnComboBox.Height + 2
tableStyle.GridColumnStyles.Add(ComboTextCol)
End If
i = i + 1
End While
DataGrid1.TableStyles.Clear()
DataGrid1.TableStyles.Add(tableStyle)
DataGrid1.DataSource = dt
End Sub
Private Sub CboenDatagrid_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
HacerDataSetYEnlazarGrid()
End Sub
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''