Click here to Skip to main content
15,885,004 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hi.

Using datagridview control to list and collect information to/from user, i was trying to create a custom datagridview column like datagridviewtextboxcolumn which turn to a combobox when enters in edit mode, which could display items for user to choose and use other combobox functions as autocomplete,etc.
After searching for identical information, i wrote a class ComboTextColumn inheriting from datagridviewcolumn, a class ComboTextCell inheriting from datagridviewtextboxcell and a class ComboTextEditingControl inheriting from combobox.
Now, it already shows the combobox when enters edit mode but i can't get items to fill the combobox item's list. I tried to inherit the combotextcolumn form datagridviewcomboboxcolumn but then i can't show cells as datagridviewtextboxcell, also tried, inheriting from datagridviewcolumn, create a property called Items where i could store items but i can't pass those items to items of the combobox that appears when enters in edit mode.

Code is like this:

Imports System
Imports System.Windows.Forms
Imports System.ComponentModel

Public Class SWComboBoxColumn
Inherits DataGridViewColumn

Private IL As New SWComboBoxItemCollection

<designerserializationvisibility(designerserializationvisibility.content)> _
Public ReadOnly Property Items() As SWComboBoxItemCollection
Get
Return IL
End Get
End Property
Public Sub New()
MyBase.New(New SWComboBoxCell())
End Sub

Public Overrides Property CellTemplate() As DataGridViewCell
Get
Return MyBase.CellTemplate
End Get
Set(ByVal value As DataGridViewCell)

' Ensure that the cell used for the template is a SWComboBoxCell.
If (value IsNot Nothing) AndAlso Not value.GetType().IsAssignableFrom(GetType(SWComboBoxCell)) Then
Throw New InvalidCastException("Must be a SWComboBoxCell")
End If
MyBase.CellTemplate = value

End Set
End Property

End Class

Public Class SWComboBoxCell
Inherits DataGridViewTextBoxCell

Public Sub New()

End Sub

Public Overrides Sub InitializeEditingControl(ByVal rowIndex As Integer, ByVal initialFormattedValue As Object, ByVal dataGridViewCellStyle As DataGridViewCellStyle)

' Set the value of the editing control to the current cell value.
MyBase.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle)

Dim ctl As SWComboBoxEditingControl = CType(DataGridView.EditingControl, SWComboBoxEditingControl)

' Use the default row value when Value property is null.
If (Me.Value Is Nothing) Then
ctl.Value = CType(Me.DefaultNewRowValue, String)
Else
ctl.Value = CType(Me.Value, String)
End If
End Sub

Public Overrides ReadOnly Property EditType() As Type
Get
' Return the type of the editing control that SWComboBoxCell uses.
Return GetType(SWComboBoxEditingControl)
End Get
End Property

Public Overrides ReadOnly Property ValueType() As Type
Get
' Return the type of the value that SWComboBoxCell contains.
Return GetType(String)
End Get
End Property

Public Overrides ReadOnly Property DefaultNewRowValue() As Object
Get
' Use the current date and time as the default value.
Return ""
End Get
End Property

End Class

Class SWComboBoxEditingControl
Inherits ComboBox
Implements IDataGridViewEditingControl

Private dataGridViewControl As DataGridView
Private valueIsChanged As Boolean = False
Private rowIndexNum As Integer

Public Sub New()

End Sub

Public Property Value() As String
Get
Return Me.Text
End Get
Set(value As String)
Me.Text = value
End Set
End Property

Public Property EditingControlFormattedValue() As Object Implements IDataGridViewEditingControl.EditingControlFormattedValue

Get
Return Me.Value.ToString()
End Get

Set(ByVal value As Object)
Try
' This will throw an exception of the string is
' null, empty, or not in the format of a date.
Me.Value = CStr(value)
Catch
' In the case of an exception, just use the default
' value so we're not left with a null value.
Me.Value = ""
End Try
End Set

End Property

Public Function GetEditingControlFormattedValue(ByVal context As DataGridViewDataErrorContexts) As Object Implements IDataGridViewEditingControl.GetEditingControlFormattedValue

Return Me.Value.ToString()

End Function

Public Sub ApplyCellStyleToEditingControl(ByVal dataGridViewCellStyle As DataGridViewCellStyle) Implements IDataGridViewEditingControl.ApplyCellStyleToEditingControl

Me.Font = dataGridViewCellStyle.Font
Me.ForeColor = dataGridViewCellStyle.ForeColor
Me.BackColor = dataGridViewCellStyle.BackColor

End Sub

Public Property EditingControlRowIndex() As Integer Implements IDataGridViewEditingControl.EditingControlRowIndex

Get
Return rowIndexNum
End Get
Set(ByVal value As Integer)
rowIndexNum = value
End Set

End Property

Public Function EditingControlWantsInputKey(ByVal key As Keys, ByVal dataGridViewWantsInputKey As Boolean) As Boolean Implements IDataGridViewEditingControl.EditingControlWantsInputKey

' Let the combobox handle the keys listed.
Select Case key And Keys.KeyCode
Case Keys.Left, Keys.Up, Keys.Down, Keys.Right, _
Keys.Home, Keys.End, Keys.PageDown, Keys.PageUp

Return True

Case Else
Return Not dataGridViewWantsInputKey
End Select

End Function

Public Sub PrepareEditingControlForEdit(ByVal selectAll As Boolean) Implements IDataGridViewEditingControl.PrepareEditingControlForEdit

' No preparation needs to be done.

End Sub

Public ReadOnly Property RepositionEditingControlOnValueChange() As Boolean Implements IDataGridViewEditingControl.RepositionEditingControlOnValueChange

Get
Return False
End Get

End Property

Public Property EditingControlDataGridView() As DataGridView Implements IDataGridViewEditingControl.EditingControlDataGridView

Get
Return dataGridViewControl
End Get
Set(ByVal value As DataGridView)
dataGridViewControl = value
End Set

End Property

Public Property EditingControlValueChanged() As Boolean Implements IDataGridViewEditingControl.EditingControlValueChanged

Get
Return valueIsChanged
End Get
Set(ByVal value As Boolean)
valueIsChanged = value
End Set

End Property

Public ReadOnly Property EditingControlCursor() As Cursor Implements IDataGridViewEditingControl.EditingPanelCursor

Get
Return MyBase.Cursor
End Get

End Property

End Class


Public Class SWComboBoxItemCollection
Inherits System.Collections.ObjectModel.Collection(Of String)

'Variable tipo lista para almacenar los nombres enumerados de los items.
Private itemsNames As New List(Of String)
Private index As Integer
'Evento que se desencadena al cambiar la colección.
Public Event Changed As EventHandler

'Sobrescribo este método para asignar el índice al nuevo item y enumerar su nombre.
'Luego envío el evento Changed.
Protected Overrides Sub InsertItem(ByVal index As Integer, ByVal item As String)
IndexName(item)
MyBase.InsertItem(index, item)
RaiseEventChanged()
End Sub

'Sobrescribo este método para enviar el evento Changed.
Protected Overrides Sub RemoveItem(ByVal index As Integer)
MyBase.RemoveItem(index)
RaiseEventChanged()
End Sub

'Método que agrega el índice del nuevo item al final de su nombre.
Private Sub IndexName(ByRef item As String)
If item = item.GetType.Name Then
Dim nIndex As Integer = 1
If itemsNames.IndexOf(item & nIndex) > -1 Then
Do Until itemsNames.IndexOf(item & nIndex) = -1
nIndex += 1
Loop
End If
item = item.GetType.Name & nIndex
item = item.GetType.Name & nIndex
itemsNames.Add(item)
End If
End Sub

'Método que envía el evento Changed y ejecuta tareas finales.
Private Sub RaiseEventChanged()
RaiseEvent Changed(Me, New System.EventArgs)
itemsNames.Clear()
For Each item As String In Me.Items
itemsNames.Add(item)
Next
End Sub

End Class

if someone could help me,... i'd appreciate a lot.
Thanks for your time, and patience
Posted

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900