Текст, превышающий ~43 700 символов, исчезает в Datagridview Vb.net

У меня есть DataGridView, который отображает записи базы данных. Проблема в том, что многие из моих очень длинных строк не отображаются в ячейках. Данные там, потому что я могу выбрать ячейку, скопировать содержимое, а затем вставить их в текстовый файл, и они там. Это похоже на то, как будто Datagridview меняет цвет текста на белый, когда превышено ~43 700 символов. Любые идеи о том, как это исправить?

Pic-Datagridview не отображает текст>~43 700 символов

Я попытался установить для ячеек обтекание текста и автоматически изменять размеры строк и столбцов, но это фактически приводит к возникновению проблемы при меньшем количестве символов (что еще хуже). Я также нашел очень старый предыдущий пост, который несколько уместен в " .NET Windows формы DataGridView Ячейки текст исчезает при программном добавлении". Однако, это происходило в 4563 символах и не было решено.

Также я использую Visual Basic.

Любая помощь будет оценена.

1 ответ

Я могу воспроизвести вашу проблему.

Метод DataGridViewTextBoxCell.Paint использует TextRenderer.DrawText метод в вызываемом методе PaintPrivate.

Этот пост описывает проблему с TextRender.MeasureText метод, возвращающий недопустимые значения, если текст превышает 43679 символов, что похоже на обнаруженный вами предел. Так как 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

Обратите внимание, что это усечение не изменяет значение базовой ячейки.

Эдир: Вышесказанное позволяет 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
Другие вопросы по тегам