1

I have a DataGridView that displays database entries. The problem is that many of my strings that are very long do not show up in the cells. The data is there because I can select the cell, copy the contents and then paste them into a text file and they are there. It is almost as though the Datagridview changes the text color to white once ~43,700 characters are exceeded. Any ideas on how to fix this?

Pic-Datagridview not displaying text >~43,700 characters

I have tried setting the cells to wraptext and autosizing the rows and the columns but that actually makes the problem occur at a lower number of characters (makes it worse). I also found a very old previous post that is somewhat relevant at ".NET Windows forms DataGridView Cell text disappears when added programatically." However, that was occurring at 4,563 characters and was not resolved.

Also, I am using Visual Basic.

Any help would be appreciated.

Jamie
  • 555
  • 3
  • 14
  • 2
    You could bind that field to a `RichTextBox` control, positioned in the proximity of the `DataGridView`. Or show just a sample of the text, adding a classic three-dots button, which, upon interaction, lets a user access the complete text in a new window. Something similar to the Visual Studio editor behaviour, when you need to inspect a string variable value. – Jimi Oct 13 '18 at 12:51
  • The exact limit is 43679 (displayed) and 43680 (not displayed). – Thomas Weller Dec 26 '21 at 18:17

1 Answers1

1

I can reproduce your issue.

The DataGridViewTextBoxCell.Paint method uses the TextRenderer.DrawText method in the called PaintPrivate Method.

This post describes an issue with the TextRender.MeasureText method returning invalid values if the text exceeds 43679 characters which is similar to the limit you discovered. Since the MeasureText also involves a call to DrawText, these two issues are linked.

A simple workaround would be to handle the DataGridView.CellFormatting Event and truncate the formatted string to magic string length.

Const magicMaxStringLength As Int32 = 43679
Private Sub DataGridView1_CellFormatting(sender As Object, e As DataGridViewCellFormattingEventArgs) Handles DataGridView1.CellFormatting
    Dim str As String = TryCast(e.Value, String)
    If str IsNot Nothing AndAlso str.Length >= 43679 Then
        e.Value = str.Substring(0, 43679)
        e.FormattingApplied = True
    End If
End Sub

Note that this truncation does not alter the underlying cell value.

Edir: The above allows the DGV to display the text, however it seems the same limitation also applies to the DataGridViewTextBoxEditingControl. Thus the text is not visible while editing. To overcome this limitation, you can swap a RichTextBox for use as the editing control.

Private rtbEdit As New RichTextBox
Private Sub DataGridView1_EditingControlShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
    Dim tb As System.Windows.Forms.DataGridViewTextBoxEditingControl = TryCast(e.Control, System.Windows.Forms.DataGridViewTextBoxEditingControl)
    If tb IsNot Nothing AndAlso tb.Text.Length >= magicMaxStringLength Then
        rtbEdit.Text = tb.Text
        rtbEdit.Margin = New Padding(0)
        rtbEdit.AutoSize = False
        rtbEdit.Font = tb.Font
        rtbEdit.ClientSize = DataGridView1.EditingPanel.ClientSize
        rtbEdit.WordWrap = False
        rtbEdit.Multiline = tb.Multiline
        DataGridView1.EditingPanel.Controls.Remove(e.Control)
        DataGridView1.EditingPanel.Controls.Add(rtbEdit)
        RemoveHandler DataGridView1.EditingPanel.VisibleChanged, AddressOf DataGridView1EditingPanel_VisibleChanged
        AddHandler DataGridView1.EditingPanel.VisibleChanged, AddressOf DataGridView1EditingPanel_VisibleChanged
        RemoveHandler DataGridView1.EditingPanel.SizeChanged, AddressOf DataGridView1EditingPanel_SizeChanged
        AddHandler DataGridView1.EditingPanel.SizeChanged, AddressOf DataGridView1EditingPanel_SizeChanged
    End If
End Sub

Private Sub DataGridView1EditingPanel_SizeChanged(sender As Object, e As EventArgs)
    RemoveHandler DataGridView1.EditingPanel.SizeChanged, AddressOf DataGridView1EditingPanel_SizeChanged
    rtbEdit.ClientSize = DataGridView1.EditingPanel.ClientSize
End Sub

Private Sub DataGridView1EditingPanel_VisibleChanged(sender As Object, e As EventArgs)
    If Not DataGridView1.EditingPanel.Visible Then
        DataGridView1.EditingPanel.Controls.Remove(rtbEdit)
        DataGridView1.CurrentCell.Value = rtbEdit.Text
        RemoveHandler DataGridView1.EditingPanel.VisibleChanged, AddressOf DataGridView1EditingPanel_VisibleChanged
    End If
End Sub
TnTinMn
  • 11,522
  • 3
  • 18
  • 39