title: Saved value is not displayed in custom datagridview column
body: <p>So I've made a custom DataGridView-Column which is showing a DropDown for multiselecting different values and displaying them with a separator.</p>
  <p><a href="https://i.stack.imgur.com/lICQZ.png" rel="nofollow noreferrer">Picture of Cell with dropdown and selectedvalues</a></p>
  <p>It's working fine so far, but the saved value is not displayed in the cell. Displaying the value after selecting them is working fine, but after reloading the cell is empty.</p>
  <p>I think I've missed an Eventhandler which initializes &quot;Me.Value&quot;...</p>
  <p>Code from Column-Class:</p>
  <pre><code>Imports System.Data
  Imports System.ComponentModel
  
  Public Class dgvCheckedComboBoxColumn
      Inherits DataGridViewColumn
  
      Private m_dt As DataTable
      &lt;Browsable(True), Category(&quot;Daten&quot;), Description(&quot;Only DataTable allowed!&quot;)&gt;
      Public Shadows Property DataSource() As DataTable
          Get
              Return m_dt
          End Get
          Set(value As DataTable)
              m_dt = value
          End Set
      End Property
  
      Private m_DisplayMember As String
      &lt;Browsable(True), Category(&quot;Daten&quot;), Description(&quot;The column that contains the displayed value in the dropdown&quot;)&gt;
      Public Shadows Property DisplayMember() As String
          Get
              Return m_DisplayMember
          End Get
          Set(value As String)
              m_DisplayMember = value
          End Set
      End Property
  
      Private m_ValueMember As String
      &lt;Browsable(True), Category(&quot;Daten&quot;), Description(&quot;ValueMember&quot;)&gt;
      Public Shadows Property ValueMember As String
          Get
              Return m_ValueMember
          End Get
          Set(value As String)
              m_ValueMember = value
              'Primary-Key von DataSource entspricht Value-Member
              If Me.DataSource IsNot Nothing Then
                  m_dt.PrimaryKey = New DataColumn() {m_dt.Columns(value)}
              End If
          End Set
      End Property
  
      Private m_CellDisplayMember As String
      &lt;Browsable(True), Category(&quot;Daten&quot;), Description(&quot;Displayed Cell-Value&quot;)&gt;
      Public Property CellDisplayMember As String
          Get
              Return If(String.IsNullOrEmpty(m_CellDisplayMember), m_DisplayMember, m_CellDisplayMember)
          End Get
          Set(value As String)
              m_CellDisplayMember = value
          End Set
      End Property
  
      Private m_DropDownWidth As Integer
      &lt;DefaultValue(150), Browsable(True), Category(&quot;Visual&quot;), Description(&quot;DropDown-Width&quot;)&gt;
      Public Property DropDownWidth As Integer
          Get
              Return m_DropDownWidth
          End Get
          Set(value As Integer)
              m_DropDownWidth = value
          End Set
      End Property
  
      Private m_UseValidation As Boolean
      &lt;DefaultValue(False), Browsable(True), Category(&quot;Data&quot;), Description(&quot;Only allow values that exist in datasource&quot;)&gt;
      Public Property UseValidation As Boolean
          Get
              Return m_UseValidation
          End Get
          Set(value As Boolean)
              m_UseValidation = value
          End Set
      End Property
  
      Public Sub New()
          MyBase.New(New dgvCheckedComboBoxCell())
          Me.CellTemplate = New dgvCheckedComboBoxCell
          Me.ReadOnly = True
      End Sub
  
      Public Overrides Function Clone() As Object
          Dim copy As dgvCheckedComboBoxColumn = TryCast(MyBase.Clone(), dgvCheckedComboBoxColumn)
          copy.DataSource = m_dt
          copy.ValueMember = m_ValueMember
          copy.DisplayMember = m_DisplayMember
          copy.CellDisplayMember = m_CellDisplayMember
          copy.DropDownWidth = m_DropDownWidth
          copy.UseValidation = m_UseValidation
  
          Return copy
      End Function
  End Class
  </code></pre>
  <p>Code from CustomCell:</p>
  <pre><code>    Imports System.Data
      
      Public Class dgvCheckedComboBoxCell
          Inherits DataGridViewTextBoxCell
      
          Private m_ucCheckList As UserControl
      
          Public Sub New()
              MyBase.New()
      
      
          End Sub
      
      #Region &quot; Properties&quot;
          Private m_CheckedValues As DataTable
          ''' &lt;summary&gt;
          ''' Contains the selected values from current cell 
          ''' &lt;/summary&gt;
          ''' &lt;returns&gt;&lt;/returns&gt;
          Public Property CheckedValues As DataTable
              Get
                  Dim col As dgvCheckedComboBoxColumn = CType(Me.OwningColumn, dgvCheckedComboBoxColumn)
                  If m_CheckedValues Is Nothing AndAlso col.DataSource IsNot Nothing Then
                      Dim dt As DataTable = DirectCast(col.DataSource, DataTable).Clone
                      m_CheckedValues = dt
                  End If
                  Return m_CheckedValues
              End Get
              Set(value As DataTable)
                  m_CheckedValues = value
              End Set
          End Property
      
          ''' &lt;summary&gt;
          ''' Contains the selected values separated by String by ValueMember
          ''' &lt;/summary&gt;
          ''' &lt;returns&gt;&lt;/returns&gt;
          Private ReadOnly Property SelectedValue As String
              Get
                  Dim col = DirectCast(Me.OwningColumn, dgvCheckedComboBoxColumn)
                  Try
                      Return String.Join(&quot;,&quot;, CheckedValues?.Rows.Cast(Of DataRow).Select(Function(r) r.Item(col.ValueMember).ToString))
                  Catch ex As Exception
                      Return &quot;&quot;
                  End Try
              End Get
          End Property
      
          Private ReadOnly Property SelectedText As String
              Get
                  Dim col = DirectCast(Me.OwningColumn, dgvCheckedComboBoxColumn)
                  Try
                      Return String.Join(&quot;,&quot;, CheckedValues?.Rows.Cast(Of DataRow).Select(Function(r) r.Item(col.CellDisplayMember).ToString))
                  Catch ex As Exception
                      Return &quot;&quot;
                  End Try
              End Get
          End Property
      #End Region
      
      
      #Region &quot; Cell-Events&quot;  
          Protected Overrides Sub OnMouseEnter(rowIndex As Integer)
              MyBase.OnMouseEnter(rowIndex)
          End Sub
      
          Protected Overrides Sub OnEnter(rowIndex As Integer, throughMouseClick As Boolean)
              MyBase.OnEnter(rowIndex, throughMouseClick)
          End Sub
      
          Protected Overrides Sub OnLeave(rowIndex As Integer, throughMouseClick As Boolean)
              If DataGridView.Controls.Contains(m_ucCheckList) Then
                  m_ucCheckList.Visible = False
              End If
              Me.Value = Me.SelectedValue
              MyBase.OnLeave(rowIndex, throughMouseClick)
          End Sub
      
          Protected Overrides Sub OnMouseClick(e As DataGridViewCellMouseEventArgs)
              MyBase.OnMouseClick(e)
              OpenDropDown()
          End Sub
      
          Private Sub OpenDropDown(Optional CursorLocation As Point = Nothing)
              Try
                  If Me.DataGridView.Columns.Count = 0 Or RowIndex = -1 Then
                      Exit Sub
                  End If
      
                  Dim col As dgvCheckedComboBoxColumn = CType(Me.OwningColumn, dgvCheckedComboBoxColumn)
                  If col.DataSource Is Nothing OrElse CType(col.DataSource, DataTable).Rows.Count = 0 Then Exit Sub
      
                  If m_ucCheckList Is Nothing Then
                      m_ucCheckList = New UserControl
                      m_ucCheckList.Padding = New Padding(5, 0, 0, 0)
                      m_ucCheckList.BorderStyle = BorderStyle.FixedSingle
                  End If
                  If Not IsNothing(CursorLocation) Then
                      Dim ctrl = DataGridView.GetChildAtPoint(CursorLocation, GetChildAtPointSkip.Disabled)
                  End If
                  SetDefaultLocationOfListBox()
      
                  Dim chk As CheckBox
                  m_ucCheckList.Controls.Clear()
                  For Each row As DataRow In DirectCast(col.DataSource, DataTable).Rows
                      chk = New CheckBox
                      chk.Text = row(col.DisplayMember).ToString
                      chk.Tag = row
                      chk.Checked = (From dr In CheckedValues.AsEnumerable
                                     Where CStr(dr(col.ValueMember)) = CStr(row(col.ValueMember))
                                     Select True).FirstOrDefault
                      chk.Dock = DockStyle.Top
                      AddHandler chk.CheckedChanged, AddressOf ChkList_CheckedChanged
                      m_ucCheckList.Controls.Add(chk)
                  Next
                  With m_ucCheckList
                      If CType(col.DataSource, DataTable).Rows.Count &gt; 20 Then
                          .Height = 250
                      Else
                          .Height = CType(col.DataSource, DataTable).Rows.Count * m_ucCheckList.Controls(0).Height
                      End If
                      .Width = col.DropDownWidth
                      If .Height &lt; 24 Then
                          .Height = 24
                      End If
                      .Show()
                      .BringToFront()
                      .Refresh()
                  End With
      
              Catch ex As Exception
      
              End Try
          End Sub
      
          Private Sub SetDefaultLocationOfListBox()
              Dim defaultPoint As Point
              Try
                  defaultPoint = GetCurrentCellPosition()
      
                  m_ucCheckList.Location = defaultPoint
                  If Not Me.DataGridView.Controls.Contains(m_ucCheckList) Then
                      Me.DataGridView.Controls.Add(m_ucCheckList)
                  End If
      
                  m_ucCheckList.Visible = True
              Catch ex As Exception
      
              End Try
          End Sub
      
          Private Function GetCurrentCellPosition() As Point
              Try
                  If Me.DataGridView IsNot Nothing AndAlso DataGridView.CurrentCell IsNot Nothing Then
                      Dim iRowHeight As Integer = DataGridView.Rows(DataGridView.CurrentCell.RowIndex).Height
                      Dim rCellRectangle As Rectangle = DataGridView.GetCellDisplayRectangle(DataGridView.CurrentCell.ColumnIndex, DataGridView.CurrentCell.RowIndex, False)
      
                      Return New Point(rCellRectangle.X, rCellRectangle.Y + iRowHeight)
                  End If
              Catch ex As Exception
      
              End Try
          End Function
      
          Protected Overrides Sub Paint(graphics As Graphics, clipBounds As Rectangle, cellBounds As Rectangle, rowIndex As Integer, cellstate As DataGridViewElementStates, value As Object,
  formattedValue As Object, errorText As String, cellStyle As DataGridViewCellStyle, advancedBorderStyle As DataGridViewAdvancedBorderStyle, paintParts As DataGridViewPaintParts)
              
  'formattedValue = SelectedText
              'value = SelectedValue
      
              MyBase.Paint(graphics, clipBounds, cellBounds, rowIndex, cellstate, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts)
          End Sub
      
          Private Sub ChkList_CheckedChanged(sender As Object, e As EventArgs)
              Dim chk As CheckBox = CType(sender, CheckBox)
              Dim row As DataRow = CType(chk.Tag, DataRow)
              Dim col = CType(Me.OwningColumn, dgvCheckedComboBoxColumn)
              If chk.Checked Then
                  Dim dr = CheckedValues.NewRow()
                  dr(col.ValueMember) = row(col.ValueMember)
                  dr(col.DisplayMember) = row(col.DisplayMember)
                  If col.CellDisplayMember &lt;&gt; col.DisplayMember Then
                      dr(col.CellDisplayMember) = row(col.CellDisplayMember)
                  End If
                  m_CheckedValues.Rows.Add(dr)
              Else
                  Dim CheckedRow = (From dr In CheckedValues.AsEnumerable
                                    Where CStr(dr(col.ValueMember)) = CStr(row(col.ValueMember))
                                    Select dr).FirstOrDefault
                  If CheckedRow IsNot Nothing Then
                      CheckedValues.Rows.Remove(CheckedRow)
                  End If
              End If
          End Sub
      
          Protected Overrides Sub OnKeyPress(e As KeyPressEventArgs, rowIndex As Integer)
              MyBase.OnKeyPress(e, rowIndex)
          End Sub
      
      #End Region
      End Class
  </code></pre>
  <p><strong>UPDATE</strong>
  I've found the problem. The value was overwritten in the paint-Event. I am going to update the code once I've finished the Bugfix.</p>