大于 ~43,700 个字符的文本在 Datagridview Vb.net 中消失



我有一个显示数据库条目的DataGridView。 问题是我的许多很长的字符串没有显示在单元格中。 数据之所以存在,是因为您可以选择单元格,复制内容,然后将它们粘贴到文本文件中,它们就在那里。 这几乎就像 Datagridview 在超过 ~43,700 个字符后将文本颜色更改为白色。 关于如何解决这个问题的任何想法?

图片数据网格视图不显示文本>~43,700 个字符

我尝试将单元格设置为换行并自动调整行和列的大小,但这实际上使问题发生在较少的字符数上(使其变得更糟(。 我还发现了一篇非常古老的上一篇文章,该文章与".NET Windows 表单 DataGridView 单元格文本在以编程方式添加时消失"有些相关。 但是,这发生在 4,563 个字符处,并且没有解决。

另外,我正在使用Visual Basic。

任何帮助将不胜感激。

我可以重现您的问题。

DataGridViewTextBoxCell.Paint 方法使用称为 PaintPrivate 方法中的TextRenderer.DrawText方法。

这篇文章描述了如果文本超过 43679 个字符,则TextRender.MeasureText方法返回无效值的问题,这类似于您发现的限制。 由于MeasureText也涉及DrawText的呼吁,这两个问题是联系在一起的。

一个简单的解决方法是处理 DataGridView.CellFormatting 事件并将格式化字符串截断为魔术字符串长度。

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

请注意,此截断不会更改基础单元格值。

Edir:上述内容允许DGV显示文本,但是似乎相同的限制也适用于DataGridViewTextBoxEditingControl。 因此,文本在编辑时不可见。 若要克服此限制,可以交换RichTextBox以用作编辑控件。

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

最新更新