Results 1 to 2 of 2

Thread: Implement Column/Cell/EditingControl derived classes, host custom ComboBox control

  1. #1

    Thread Starter
    Member VBobCat's Avatar
    Join Date
    Sep 2011
    Location
    São Paulo, Brazil
    Posts
    34

    Implement Column/Cell/EditingControl derived classes, host custom ComboBox control

    I have this custom Control class, derived from ComboBox. Its purpose is to provide a standard behavior for controls whose list of items will be populated depending on what user types in it as search criteria.
    vb Code:
    1. Imports System.ComponentModel
    2. Public Class SearchBox
    3. Inherits ComboBox
    4.  
    5. Private hasTextChanged As Boolean
    6.  
    7. Private _queryInterval As Integer = 3000
    8. Public Property QueryInterval As Integer
    9. Get
    10. Return _queryInterval
    11. End Get
    12. Set(value As Integer)
    13. _queryInterval = value
    14. If _myTimer IsNot Nothing Then _myTimer.Interval = value
    15. End Set
    16. End Property
    17.  
    18. Private WithEvents _myTimer As Timer
    19. Private ReadOnly Property MyTimer As Timer
    20. Get
    21. If _myTimer Is Nothing Then
    22. _myTimer = New Timer() With {.Enabled = False, .Interval = QueryInterval}
    23. End If
    24. Return _myTimer
    25. End Get
    26. End Property
    27.  
    28. Private WithEvents _myPictureBox As PictureBox
    29. Private ReadOnly Property MyPictureBox As PictureBox
    30. Get
    31. If _myPictureBox Is Nothing Then
    32. _myPictureBox = New PictureBox() With {
    33. .BackColor = Color.Transparent,
    34. .BorderStyle = BorderStyle.None,
    35. .Parent = Me,
    36. .Height = Height - 2,
    37. .Width = Height - 2,
    38. .Top = 1,
    39. .Left = Width - Height,
    40. .Visible = False,
    41. .SizeMode = PictureBoxSizeMode.CenterImage}
    42. _myPictureBox.Image = Image.FromStream(
    43. New IO.MemoryStream(
    44. Convert.FromBase64String(
    45. "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")))
    46. End If
    47. Return _myPictureBox
    48. End Get
    49. End Property
    50.  
    51. Friend Property WaitingIcon As Boolean
    52. Get
    53. Return MyPictureBox.Visible
    54. End Get
    55. Set(value As Boolean)
    56. MyPictureBox.Visible = value
    57. End Set
    58. End Property
    59.  
    60. Public Shadows Property DataSource As DataTable
    61. Get
    62. Return MyBase.DataSource
    63. End Get
    64. Set(value As DataTable)
    65. MyBase.DataSource = value
    66. End Set
    67. End Property
    68.  
    69. Public Shadows Property SelectedItem As DataRowView
    70. Get
    71. Return MyBase.SelectedItem
    72. End Get
    73. Set(value As DataRowView)
    74. MyBase.SelectedItem = value
    75. End Set
    76. End Property
    77.  
    78. Private Sub _myTimer_Tick(sender As Object, e As EventArgs) Handles _myTimer.Tick
    79. MyTimer.Stop()
    80. SendKeys.Send("{TAB}")
    81. End Sub
    82.  
    83. Protected Overrides Sub OnKeyDown(e As KeyEventArgs)
    84. MyTimer.Stop()
    85. If e.KeyValue = 13 Then e.SuppressKeyPress = True
    86. MyBase.OnKeyDown(e)
    87. End Sub
    88.  
    89. Protected Overrides Sub OnKeyUp(e As KeyEventArgs)
    90. If e.KeyValue = 13 Then e.SuppressKeyPress = True
    91. MyBase.OnKeyUp(e)
    92. If e.KeyValue = 13 Then
    93. SendKeys.Send("{TAB}")
    94. ElseIf hasTextChanged
    95. hasTextChanged = False
    96. MyTimer.Stop()
    97. MyTimer.Start()
    98. End If
    99. End Sub
    100.  
    101. Protected Overrides Sub OnTextChanged(e As EventArgs)
    102. hasTextChanged = True
    103. MyBase.OnTextChanged(e)
    104. End Sub
    105.  
    106. Protected WithEvents BGW As New BackgroundWorker
    107. Private work As Action, whenDone As Action
    108. Protected Sub DoAction(ByVal work As Action, whendone As Action)
    109. Me.work = work
    110. Me.whenDone = whendone
    111. BGW.RunWorkerAsync()
    112. End Sub
    113. Private Sub BGW_DoWork(sender As Object, e As DoWorkEventArgs) Handles BGW.DoWork
    114. Invoke(Sub() WaitingIcon = True)
    115. If work IsNot Nothing Then work.Invoke
    116. End Sub
    117. Private Sub BGW_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles BGW.RunWorkerCompleted
    118. Invoke(Sub() WaitingIcon = False)
    119. If whenDone IsNot Nothing Then BeginInvoke(whenDone)
    120. End Sub
    121. End Class

    These controls are working as expected, but now I would like my DataGridViews to host cells that behaved just like these. I tried to follow an example I found on web and wrote those classes below. However, it never worked. It raises the same exception in DataGridView's standard erro dialog, once when it is loaded and again repeats forever whenever I try to click it: System.FormatException: The property FormattedValueType of a cell cannot be null.
    vb Code:
    1. Public Class SearchColumn
    2. Inherits DataGridViewColumn
    3. Public Sub New()
    4. MyBase.New(New SearchCell())
    5. End Sub
    6. Public Overrides Property CellTemplate() As DataGridViewCell
    7. Get
    8. Return MyBase.CellTemplate
    9. End Get
    10. Set(value As DataGridViewCell)
    11. If (value IsNot Nothing) AndAlso
    12. Not value.GetType().IsAssignableFrom(GetType(SearchCell)) _
    13. Then
    14. Throw New InvalidCastException("Must be a SearchCell")
    15. End If
    16. MyBase.CellTemplate = value
    17. End Set
    18. End Property
    19. End Class
    20.  
    21. Public Class SearchCell
    22. Inherits DataGridViewCell
    23. Public Overrides Sub InitializeEditingControl(ByVal rowIndex As Integer,
    24. ByVal initialFormattedValue As Object,
    25. ByVal dataGridViewCellStyle As DataGridViewCellStyle)
    26.  
    27. ' Set the value of the editing control to the current cell value.
    28. MyBase.InitializeEditingControl(rowIndex, initialFormattedValue,
    29. dataGridViewCellStyle)
    30.  
    31. Dim ctl As SearchEditingControl =
    32. CType(DataGridView.EditingControl, SearchEditingControl)
    33.  
    34. ' Use the default row value when Value property is null.
    35. If (Me.Value Is Nothing) Then
    36. ctl.Text = CStr(Me.DefaultNewRowValue).Assert
    37. Else
    38. ctl.Text = CStr(Me.Value).Assert
    39. End If
    40. End Sub
    41. End Class
    42.  
    43. Class SearchEditingControl
    44. Inherits PessBox
    45. Implements IDataGridViewEditingControl
    46.  
    47. Private dataGridViewControl As DataGridView
    48. Private valueIsChanged As Boolean = False
    49. Private rowIndexNum As Integer
    50.  
    51. Public Property EditingControlDataGridView As DataGridView Implements IDataGridViewEditingControl.EditingControlDataGridView
    52. Get
    53. Return dataGridViewControl
    54. End Get
    55. Set(value As DataGridView)
    56. dataGridViewControl = value
    57. End Set
    58. End Property
    59.  
    60. Public Property EditingControlFormattedValue As Object Implements IDataGridViewEditingControl.EditingControlFormattedValue
    61. Get
    62. Return Me.Text.Assert
    63. End Get
    64. Set(value As Object)
    65. Me.Text = CStr(value).Assert
    66. End Set
    67. End Property
    68.  
    69. Public Property EditingControlRowIndex As Integer Implements IDataGridViewEditingControl.EditingControlRowIndex
    70. Get
    71. Return rowIndexNum
    72. End Get
    73. Set(ByVal value As Integer)
    74. rowIndexNum = value
    75. End Set
    76. End Property
    77.  
    78. Public Property EditingControlValueChanged As Boolean Implements IDataGridViewEditingControl.EditingControlValueChanged
    79. Get
    80. Return valueIsChanged
    81. End Get
    82. Set(value As Boolean)
    83. valueIsChanged = value
    84. End Set
    85. End Property
    86.  
    87. Public ReadOnly Property EditingPanelCursor As Cursor Implements IDataGridViewEditingControl.EditingPanelCursor
    88. Get
    89. Return MyBase.Cursor
    90. End Get
    91. End Property
    92.  
    93. Public ReadOnly Property RepositionEditingControlOnValueChange As Boolean Implements IDataGridViewEditingControl.RepositionEditingControlOnValueChange
    94. Get
    95. Return False
    96. End Get
    97. End Property
    98.  
    99. Public Sub ApplyCellStyleToEditingControl(dataGridViewCellStyle As DataGridViewCellStyle) Implements IDataGridViewEditingControl.ApplyCellStyleToEditingControl
    100. Me.Font = dataGridViewCellStyle.Font
    101. Me.ForeColor = dataGridViewCellStyle.ForeColor
    102. Me.BackColor = dataGridViewCellStyle.BackColor
    103. End Sub
    104.  
    105. Public Sub PrepareEditingControlForEdit(selectAll As Boolean) Implements IDataGridViewEditingControl.PrepareEditingControlForEdit
    106. ' No preparation needs to be done.
    107. End Sub
    108.  
    109. Public Function EditingControlWantsInputKey(keyData As Keys, dataGridViewWantsInputKey As Boolean) As Boolean Implements IDataGridViewEditingControl.EditingControlWantsInputKey
    110. Select Case keyData And Keys.KeyCode
    111. Case Keys.Left, Keys.Up, Keys.Down, Keys.Right, Keys.Home, Keys.End, Keys.PageDown, Keys.PageUp
    112. Return True
    113. Case Else
    114. Return Not dataGridViewWantsInputKey
    115. End Select
    116. End Function
    117.  
    118. Public Function GetEditingControlFormattedValue(context As DataGridViewDataErrorContexts) As Object Implements IDataGridViewEditingControl.GetEditingControlFormattedValue
    119. Return Me.Text.Assert
    120. End Function
    121.  
    122. Protected Overrides Sub OnTextChanged(e As EventArgs)
    123. valueIsChanged = True
    124. Me.EditingControlDataGridView.NotifyCurrentCellDirty(True)
    125. MyBase.OnTextChanged(e)
    126. End Sub
    127.  
    128. End Class

    Any help you guys could give me, or directions for properly implementing this, will be deeply appreciated. Thanks!
    VBobCat
    VS2013 & Office-VBA
    Autodidact, part-time programmer for job needs

  2. #2
    Frenzied Member
    Join Date
    May 2014
    Location
    Central Europe
    Posts
    1,372

    Re: Implement Column/Cell/EditingControl derived classes, host custom ComboBox contro

    it will help to get an answer if you could clean up the code a bit to have a nice litte reproducable sample of your problem. things like new pictureboxes loaded with a pic from base64 strings and backgroundworkers have nothing to do with your problem, i'd say you can omit these

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width