Click here to Skip to main content
15,891,033 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi I'm creating a custom datagridviewcolumn and need to create a property Items, just like the Items property of the DataGridViewComboBoxColumn.
I tried the following declaration:

VB
Private It As DataGridViewComboBoxCell.ObjectCollection

        <DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
        Public Property Items As DataGridViewComboBoxCell.ObjectCollection
            Get
                Return It
            End Get
            Set(value As DataGridViewComboBoxCell.ObjectCollection)
                It = value
            End Set
        End Property


but when i access datagrid's column's property, it shows a different editor, in fact, i can't assign values to the list.
I tried then to declare the property as String() and it appears correct, unless that i lost access to the methods of the collection. Tried too as IList(Of String) and ICollection(Of String) but it behaves like the first try.
I'd appreciate any help that you could give.
Thanks in advance
Posted
Comments
Sergey Alexandrovich Kryukov 12-Dec-13 9:23am    
I answered your question, but...
You always need to tag platform, language and other detail, such as ".NET", "VB.NET". Most people don't like guesswork. And you are the one interested the most in correct tags and question title, so your page could attract right people before they even open it.
—SA
Ranopi 12-Dec-13 19:27pm    
Sorry for any i did that offended you. i'm writing in VB.NET
My intention is to create a new datagridcolumn that displays a textboxcell when not in edit mode, and a combobox when it enters edit mode.
I tried to inherits from comboboxcolumn, but then i can't the celltemplate as textbox cell. as i needed to clone the property, couldn't declare as readonly.

so far i solved that problem. but then i got another one.
code is like this:

Public Class CBColumn
Inherits DataGridViewColumn

#Region "Propriedades"

Private DV As String

<category("dados"), description("valor="" a="" mostrar="" nas="" celulas="" pertencentes="" esta="" coluna="" quando="" são="" criadas"),="" _
="" designerserializationvisibility(designerserializationvisibility.visible)=""> _
Public Property DefaultValue() As String
Get
Return DV
End Get
Set(value As String)
If DV <> value Then
Dim CBCel As New CBCell
DV = value
' First, update the value on the template cell.
CBCel = DirectCast(Me.CellTemplate, CBCell)
CBCel.ColumnsDefaultValue = value
' Now set it on all cells in other rows as well.
Dim DgvCel As DataGridViewCell
Dim RowCount As Integer
If Me.DataGridView IsNot Nothing AndAlso Me.DataGridView.Rows IsNot Nothing Then
RowCount = Me.DataGridView.Rows.Count
For x As Integer = 0 To RowCount - 1
DgvCel = Me.DataGridView.Rows.SharedRow(x).Cells(x)
If TypeOf DgvCel Is CBCell Then
CBCel = CType(DgvCel, CBCell)
CBCel.ColumnsDefaultValue = value
Me.DataGridView.CurrentCell = CBCel
End If
Next
End If
End If
End Set
End Property

Private It As New ObjectModel.Collection(Of String) 'CBItemCollection

<category("dados"), description("items="" a="" mostrar="" na="" lista="" nas="" celulas="" pertencentes="" esta="" coluna="" quando="" são="" criadas")=""> _
<designerserializationvisibility(designerserializationvisibility.content)> _
Public Property DefaultItems() As ObjectModel.Collection(Of String) ' CBItemCollection
Get
Return It
End Get
Set(value As ObjectModel.Collection(Of String))
If Not Collection.Equals(It, value) Then
Dim CBCel As New CBCell
It = value
' First, update the value on the template cell.
CBCel = DirectCast(Me.CellTemplate, CBCell)
CBCel.Items = value
' Now set it on all cells in other rows as well.
Dim DgvCel As DataGridViewCell
Dim RowCount As Integer
If Me.DataGridView IsNot Nothing AndAlso Me.DataGridView.Rows IsNot Nothing Then
RowCount = Me.DataGridView.Rows.Count
For x As Integer = 0 To RowCount - 1
DgvCel = Me.DataGridView.Rows.SharedRow(x).Cells(x)
If TypeOf DgvCel Is CBCell Then
CBCel = CType(DgvCel, CBCell)
CBCel.Items = value
Me.DataGridView.CurrentCell = CBCel
End If
Next
End If
End If

End Set
End Property

Public Overrides Property CellTemplate() As DataGridViewCell
Get
Return MyBase.CellTemplate
End Get
Set(ByVal value As DataGridViewCell)
' Ensure that the cell used for
Ranopi 12-Dec-13 19:51pm    
the template is a CBCell.
If (value IsNot Nothing) AndAlso Not value.GetType().IsAssignableFrom(GetType(CBCell)) Then
Throw New InvalidCastException("Must be a CBCell")
End If
MyBase.CellTemplate = value
End Set
End Property

#End Region

#Region "Procedimentos"

Public Sub New()
MyBase.New(New CBCell())
End Sub

Public Overrides Function Clone() As Object

Dim col As CBColumn = CType(MyBase.Clone, CBColumn)
'Class variables=Private variables
col.DefaultValue = DV
col.DefaultItems = It
Return col
End Function

#End Region

End Class

Public Class CBCell
Inherits DataGridViewTextBoxCell


#Region "Propriedades"

Private DV As String

<designerserializationvisibility(designerserializationvisibility.visible)> _
Public Property ColumnsDefaultValue() As String
Get
Return DV
End Get
Set(value As String)
If DV <> value Then
DV = value
Me.Value = DV
End If
End Set
End Property

Private It As CBItemCollection

<designerserializationvisibility(designerserializationvisibility.content)> _
Public Property Items() As CBItemCollection
Get
Return It
End Get
Set(value As CBItemCollection)
It = value
End Set
End Property

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

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

Public Overrides ReadOnly Property DefaultNewRowValue() As Object
Get
' Use an empty string as the default value.
Return ""
End Get

End Property

#End Region

#Region "Procedimentos"

Public Sub New()

End Sub

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

Dim CbEdCtrl As CBEditingControl
Dim CbxColumn As CBColumn
Dim dgvColumn As DataGridViewColumn

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

CbEdCtrl = CType(DataGridView.EditingControl, CBEditingControl)

' Set up props that are specific to the MaskedTextBox

dgvColumn = Me.OwningColumn

If TypeOf dgvColumn Is CBColumn Then
CbxColumn = CType(dgvColumn, CBColumn)
End If

' repetir seguinte codigo para cada propriedade a passar para o editingcontrol

If (Me.Value Is Nothing) Then
CbEdCtrl.Text = CType(Me.DefaultNewRowValue, String)
Else
CbEdCtrl.Text = CType(Me.Value, String)
End If

If (Me.Items Is Nothing) Then
CbEdCtrl.Items.Clear()
CbEdCtrl.Items.AddRange(CbxColumn.DefaultItems.ToArray())
Else
CbEdCtrl.Items.Clear()
For Each i As String In Me.Items.ToArray()
CbEdCtrl.Items.Add(i)
'MsgBox(i)
Next
End If

End Sub

Public Overrides Function Clone() As Object
'Class variables=Private variables
Ranopi 12-Dec-13 19:53pm    
Public Class CBEditingControl
Inherits ComboBox
Implements IDataGridViewEditingControl

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

#Region "Propriedades"

Public Property EditingControlFormattedValue() As Object Implements IDataGridViewEditingControl.EditingControlFormattedValue

Get
Return Me.Text
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.Text = CStr(value)
Catch
' In the case of an exception, just use the default
' value so we're not left with a null value.
Me.Text = ""
End Try
End Set

End Property

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 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 Region

#Region "Procedimentos"

Public Sub New()

End Sub

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

Return Me.Text

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 Function EditingControlWantsInputKey(ByVal key As Keys, ByVal dataGridViewWantsInputKey As Boolean) As Boolean Implements IDataGridViewEditingControl.EditingControlWantsInputKey

' Let the DateTimePicker 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

Protected Overrides Sub OnTextChanged(eventargs As EventArgs)
' Notify the DataGridView

First of all, it should be read-only property. You create a private collection member initialized at the point of declaration. Your property getter should return this reference, and setter should be absent.

Now, are you trying to have the collection of the items of DataGridViewComboBoxCell type? Then why not using existing DataGridViewComboBoxColumn? If you really need a custom column type, you first need to create a custom type of the cell, derived from one of existing cell type, typically abstract DataGridViewCell, create a collection of such cells and use it in your custom column type.

—SA
 
Share this answer
 
Well, after trying different possible solutions i got it right. Problem solved.
Here is the resumed solution. I'll post an article later with a complete solution and explanations of creating custom datagridviewcolumn.
In the column class declare items property as:

VB
Private It As New ObjectModel.Collection(Of String) 'CBItemCollection

        <category("data"),> _
        <designerserializationvisibility(designerserializationvisibility.content)> _
        Public ReadOnly Property DefaultItems() As ObjectModel.Collection(Of String) ' CBItemCollection
            Get
                Return It
            End Get
        End Property

In the cell class declare items property as:

VB
Private It As New ObjectModel.Collection(Of String)
        

<designerserializationvisibility(designerserializationvisibility.content)> _
        Public ReadOnly Property Items() As ObjectModel.Collection(Of String)
            Get
                If It.Count = 0 Then
                    Dim col As CBColumn
                    col = CType(Me.OwningColumn, CBColumn)
                    It.Clear()
                    For Each i As String In col.DefaultItems
                        It.Add(i)
                    Next
                End If
                Return It
            End Get
        End Property


Items property in cell class will allow to set different items for each cell if you wish so.
in the initializeeditingcontrol procedure insert the following code to add items to the combobox items of editingcontrol:

VB
CbEdCtrl.Items.Clear()
For Each i As String In Me.Items
    CbEdCtrl.Items.Add(i)
Next


And that is all is needed.
by default all cells contains defaultitems assign to DefaultItems of CBColumn.
to change items, just need to insert following code on the application that is being written:

VB
Dim cel As SoftWakeControls.CBCell
cel = CType(DataGridView1.CurrentCell, SoftWakeControls.CBCell)
cel.Items.Add("New item")


And that's all. Thank for your help
 
Share this answer
 

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