vb.netdatatablecustom-cellcomponentonetruedbgrid

ComponentOne True DBGrid Creating Custom Cells


First thanks for your help.

This is in regards to Componentone's True DBGrid, so this may not be the best place to expect answers, but at this point I feel like I've done as much as I can so I'm willing to give it a shot.

I've spent quite some time the last couple of days trying to figure out how I can create a custom cells within a True DBGrid, and currently I'm stuck. I've gone through as much documentation as I can find, and all of the tutorials for the True DBGrid however the farthest I can get is shown in the attached image below.

Example of One Custom Column Displayed

Here if you double click on a cell I can get a Custom Control to appear in the cell they clicked upon. However, I want the cell to be visible all the time not just when it's clicked, and I want it to be based upon the row itself not just the displayColumn like I'm doing now where I reload the "DisplayColumn.DataColumn.Editor" each time a different cell is clicked on. My code for this performance is shown below.

' Retrieve Column
Dim objPrefDisplayColumn As C1.Win.C1TrueDBGrid.C1DisplayColumn = Me.TestGrid.Splits(0).DisplayColumns("ColumnFieldName")
'Retrieve data from database
Dim data As DataTable = ' My call to database table goes here Retrieve data that relates to row
' Create Custom Controller and Insert Data from table into it
Dim prvNewCellList As New TestCellList
prvNewCellList.LabelButtonHeight = Me.TestGrid.RowHeight / pref.Rows.Count
prvNewCellList.LabelWidth = (objPrefDisplayColumn.Width * 0.9)
prvNewCellList.ButtonWidth = (objPrefDisplayColumn.Width * 0.1)
 prvNewCellList.Action_LoadUI(data)
' Assign Custom Controller to Column
objPrefDisplayColumn.DataColumn.Editor = prvNewCellList
objPrefDisplayColumn.Button = True
objPrefDisplayColumn.ButtonAlways = True
objPrefDisplayColumn.DropDownList = False
objPrefDisplayColumn.DataColumn.DropDown = Nothing

I know this should be possible when I look at tutorials for DataGridView like the link below where they place in a custom "DataGridViewTextBoxCell", like the images show.

Turtorial for Custom DataGridViewCells

Based upon what I read regarding TrueDBGrid, and the expected logic that ComponentOne most likely used DataGridView as a template for creating TrueDBGrid, I would expect the way of creating custom cells would be very similar. However, after trying to recreate this example using TrueDBGrid like shown below, I found that columns did not accept "DataGridViewColumn" and when I tried changing this to "C1DataColumn" to meet its expectations I found that the class had nothing similar to the field "CellTemplate" that could be used to create custom cells. At this point I'm almost ready to believe that the functionality for custom cells was forgotten during development of TrueDBGrid however, I am more then ready to be proven wrong.

Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Try
            Dim col As New DataGridViewRolloverCellColumn()
            Me.TestGrid.Columns.Add(col)
        Catch ex As Exception
            MsgBox("error arrose", vbInformation, "error")
        End Try
    End Sub
End Class

Public Class DataGridViewRolloverCellColumn
    Inherits DataGridViewColumn

    Public Sub New()
        Me.CellTemplate = New DataGridViewRolloverCell()
    End Sub

End Class

Public Class DataGridViewRolloverCell
    Inherits DataGridViewTextBoxCell

    Protected Overrides Sub Paint( _
    ByVal graphics As Graphics, _
    ByVal clipBounds As Rectangle, _
    ByVal cellBounds As Rectangle, _
    ByVal rowIndex As Integer, _
    ByVal elementState As DataGridViewElementStates, _
    ByVal value As Object, _
    ByVal formattedValue As Object, _
    ByVal errorText As String, _
    ByVal cellStyle As DataGridViewCellStyle, _
    ByVal advancedBorderStyle As DataGridViewAdvancedBorderStyle, _
    ByVal paintParts As DataGridViewPaintParts)

        ' Call the base class method to paint the default cell appearance.
        MyBase.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, _
            value, formattedValue, errorText, cellStyle, _
            advancedBorderStyle, paintParts)

        ' Retrieve the client location of the mouse pointer.
        Dim cursorPosition As Point = _
            Me.DataGridView.PointToClient(Cursor.Position)

        ' If the mouse pointer is over the current cell, draw a custom border.
        If cellBounds.Contains(cursorPosition) Then
            Dim newRect As New Rectangle(cellBounds.X + 1, _
                cellBounds.Y + 1, cellBounds.Width - 4, _
                cellBounds.Height - 4)
            graphics.DrawRectangle(Pens.Red, newRect)
        End If
    End Sub
End Class

Thanks again for the help


Solution

  • After some time I found a work around.

    The following solution places a common control over the cell and gives the appearance that it exists within when in reality it simply exists above it. To do this solution you need to add the common control to the grid's controller and update the common control position and visibility every time the paint event is called.

    Private Sub LoadGrid()
        ' Create and Load Common control
        Dim prvsdServiceDelivery As ServiceDelTable = New ServiceDelTable()
        prvsdServiceDelivery.Action_LoadUI(DataTable)
        ' Add Common Control to Datastruct so it can be accessed anytime
        Dictionary.put(key, prvsdServiceDelivery)
        ' insert hosted control into grid
        C1TrueDBGrid.Controls.Add(prvptPreferences)
    End Sub
    
    Private Sub TestGrid_Paint(sender As Object, e As PaintEventArgs) Handles TestGrid.Paint
    
        For Each item As KeyValuePair(Of String, prvsdServiceDelivery) In Dictionary
            Try
                Dim prvsdServiceDelivery as ServiceDelTable  = item.Value
    
                ' get cell rect, may throw error if cell is outside the bounds of table's rectangle
                Dim bnds As Rectangle = frc1tdOwnerTable.Splits(0).GetCellBounds(row,C1TrueDBGrid.Splits(0).DisplayColumns.IndexOf(column))
    
                ' Set Visibility and move if error isn't thrown
                prvsdServiceDelivery.Bounds = bnds
                prvsdServiceDelivery.Visible = True
            Catch ex As Exception
                ' Set as invisible if exception thrown to say not found
                prvsdServiceDelivery.Visible = False
            End Try
        Next
    End Sub