Following this article
RichTextBox Cell in a DataGridView[
^]
i built a typed datagridview with richtextbox cells.
But when i try to bind a DataTable to the DataGridView, the DataTable exhibit the DataColumn.DataType property as normal string, and it pass a normal string.
The DataGridView show it as normal string and lost the rtf formatting.
Does someone know some ways to bind correctly the rtf datas to a typed DataGridView?
Form code
Private dt As DataTable
Private dgv As DataGridView
Private b_Rtb_Dgv, b_Dt_Dgv As Button
Private rbRtb, rbDt As RadioButton
Private rtb As RichTextBox
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.Size = New Size(350, 380)
Me.Location = New Point(0, 0)
Me.Text = "Form1"
rbRtb = New RadioButton
With rbRtb
.Size = New Size(100, 30)
.Location = New Point(10, 10)
.Text = "RichTextBox"
.Checked = True
AddHandler .Click, AddressOf rb_Click
End With
Me.Controls.Add(rbRtb)
rbDt = New RadioButton
With rbDt
.Size = New Size(100, 30)
.Location = New Point(10, 40)
.Text = "DataTable"
.Checked = False
AddHandler .Click, AddressOf rb_Click
End With
Me.Controls.Add(rbDt)
dt = New DataTable
With dt
.Columns.Add("col1", GetType(String))
.Rows.Add()
End With
dgv = New DataGridView
With dgv
.AllowUserToAddRows = False
.AllowUserToDeleteRows = False
.AllowUserToResizeColumns = False
.AllowUserToResizeRows = False
.ColumnHeadersVisible = False
.RowHeadersVisible = False
.RowsDefaultCellStyle.WrapMode = DataGridViewTriState.True
.Size = New Size(300, 100)
.Location = New Point(10, 80)
.RowTemplate.Height = .Size.Height
loadDgv()
End With
Me.Controls.Add(dgv)
b_Rtb_Dgv = New Button
With b_Rtb_Dgv
.Size = New Size(200, 23)
.Location = New Point(110, 10)
.Text = "RichTextBox --> DataGridView"
AddHandler .Click, AddressOf b_Rtb_Dgv_Click
.Enabled = True
End With
Me.Controls.Add(b_Rtb_Dgv)
b_Dt_Dgv = New Button
With b_Dt_Dgv
.Size = New Size(200, 23)
.Location = New Point(110, 40)
.Text = "DataTable --> DataGridView"
AddHandler .Click, AddressOf b_Dt_Dgv_Click
.Enabled = False
End With
Me.Controls.Add(b_Dt_Dgv)
rtb = New RichTextBox
With rtb
.Size = New Size(300, 120)
.Location = New Point(10, 200)
.Rtf = "{\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fnil\fcharset0 Calibri;}} \viewkind4\uc1\pard\sa200\sl276\slmult1\lang16\b\f0\fs36 Donald\b0\fs22\par \i Duck\i0\par } "
End With
Me.Controls.Add(rtb)
End Sub
Private Sub loadDgv()
With dgv
Select Case rbRtb.Checked
Case True
.DataSource = Nothing
.AutoGenerateColumns = False
.Rows.Clear()
.Columns.Clear()
.Columns.Add(New DataGridViewRichTextBoxColumn)
.Rows.Add(New DataGridViewRichTextBoxCell)
Case False
If .AutoGenerateColumns = False Then
.Rows.Clear()
.Columns.Clear()
.AutoGenerateColumns = True
.DataSource = dt
End If
End Select
.Columns.Item(0).Width = .Size.Width - 3
End With
End Sub
Private Sub rb_Click()
Select Case rbRtb.Checked
Case True
If b_Rtb_Dgv.Enabled = False Then b_Rtb_Dgv.Enabled = True : b_Dt_Dgv.Enabled = False
Case False
If b_Dt_Dgv.Enabled = False Then b_Dt_Dgv.Enabled = True : b_Rtb_Dgv.Enabled = False
End Select
loadDgv()
End Sub
Public Shared Function TextToRTF(ByVal RTFtext As String) As String
Dim data_object As New DataObject
data_object.SetData(DataFormats.Rtf, RTFtext)
Return data_object.GetData(DataFormats.Rtf)
End Function
Private Sub b_Rtb_Dgv_Click(sender As Object, e As EventArgs)
Me.dgv.Rows(0).Cells(0).Value = Me.rtb.Rtf
End Sub
Private Sub b_Dt_Dgv_Click(sender As Object, e As EventArgs)
dt.Rows(0)(0) = Me.rtb.Rtf
rtb.Rtf = dt.Rows(0)(0)
End Sub
End Class
DataGridView RichTextFormat class
Imports System.ComponentModel
Public Class DataGridViewRichTextBoxColumn
Inherits DataGridViewColumn
Public Sub New()
MyBase.New(New DataGridViewRichTextBoxCell())
End Sub
Public Overrides Property CellTemplate() As DataGridViewCell
Get
Return MyBase.CellTemplate
End Get
Set(value As DataGridViewCell)
If Not (TypeOf value Is DataGridViewRichTextBoxCell) Then
Throw New InvalidCastException("CellTemplate must be a DataGridViewRichTextBoxCell")
End If
MyBase.CellTemplate = value
End Set
End Property
End Class
Public Class DataGridViewRichTextBoxCell
Inherits DataGridViewImageCell
Private Shared ReadOnly _editingControl As New RichTextBox()
Public Overrides ReadOnly Property EditType() As Type
Get
Return GetType(DataGridViewRichTextBoxEditingControl)
End Get
End Property
Public Overrides Property ValueType() As Type
Get
Return GetType(String)
End Get
Set(value As Type)
MyBase.ValueType = value
End Set
End Property
Public Overrides ReadOnly Property FormattedValueType() As Type
Get
Return GetType(String)
End Get
End Property
Private Shared Sub SetRichTextBoxText(ctl As RichTextBox, text As String)
Try
ctl.Rtf = text
Catch generatedExceptionName As ArgumentException
End Try
End Sub
Private Function GetRtfImage(rowIndex As Integer, value As Object, selected As Boolean) As Image
Dim cellSize As Size = GetSize(rowIndex)
If cellSize.Width < 1 OrElse cellSize.Height < 1 Then
Return Nothing
End If
Dim ctl As RichTextBox = Nothing
If ctl Is Nothing Then
ctl = _editingControl
ctl.Size = GetSize(rowIndex)
SetRichTextBoxText(ctl, Convert.ToString(value))
End If
If ctl IsNot Nothing Then
Dim imgSize As New Size(cellSize.Width - 1, cellSize.Height - 1)
Dim rtfImg As Image = Nothing
If selected Then
ctl.BackColor = DataGridView.DefaultCellStyle.SelectionBackColor
ctl.ForeColor = DataGridView.DefaultCellStyle.SelectionForeColor
rtfImg = RichTextBoxPrinter.Print(ctl, imgSize.Width, imgSize.Height)
ctl.BackColor = DataGridView.DefaultCellStyle.BackColor
ctl.ForeColor = DataGridView.DefaultCellStyle.ForeColor
Else
rtfImg = RichTextBoxPrinter.Print(ctl, imgSize.Width, imgSize.Height)
End If
Return rtfImg
End If
Return Nothing
End Function
Public Overrides Sub InitializeEditingControl(rowIndex As Integer, initialFormattedValue As Object, dataGridViewCellStyle As DataGridViewCellStyle)
MyBase.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle)
Dim ctl As RichTextBox = TryCast(DataGridView.EditingControl, RichTextBox)
If ctl IsNot Nothing Then
SetRichTextBoxText(ctl, Convert.ToString(initialFormattedValue))
End If
End Sub
Protected Overrides Function GetFormattedValue(value As Object, rowIndex As Integer, ByRef cellStyle As DataGridViewCellStyle, valueTypeConverter As TypeConverter, formattedValueTypeConverter As TypeConverter, context As DataGridViewDataErrorContexts) As Object
Return value
End Function
Protected Overrides Sub Paint(graphics As Graphics, clipBounds As Rectangle, cellBounds As Rectangle, rowIndex As Integer, cellState As DataGridViewElementStates, value As Object, _
formattedValue As Object, errorText As String, cellStyle As DataGridViewCellStyle, advancedBorderStyle As DataGridViewAdvancedBorderStyle, paintParts As DataGridViewPaintParts)
MyBase.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, Nothing, _
Nothing, errorText, cellStyle, advancedBorderStyle, paintParts)
Dim img As Image = GetRtfImage(rowIndex, value, MyBase.Selected)
If img IsNot Nothing Then
graphics.DrawImage(img, cellBounds.Left, cellBounds.Top)
End If
End Sub
#Region "Handlers of edit events, copyied from DataGridViewTextBoxCell"
Private flagsState As Byte
Protected Overrides Sub OnEnter(rowIndex As Integer, throughMouseClick As Boolean)
MyBase.OnEnter(rowIndex, throughMouseClick)
If (MyBase.DataGridView IsNot Nothing) AndAlso throughMouseClick Then
Me.flagsState = CByte(Me.flagsState Or 1)
End If
End Sub
Protected Overrides Sub OnLeave(rowIndex As Integer, throughMouseClick As Boolean)
MyBase.OnLeave(rowIndex, throughMouseClick)
If MyBase.DataGridView IsNot Nothing Then
Me.flagsState = CByte(Me.flagsState And -2)
End If
End Sub
Protected Overrides Sub OnMouseClick(e As DataGridViewCellMouseEventArgs)
MyBase.OnMouseClick(e)
If MyBase.DataGridView IsNot Nothing Then
Dim currentCellAddress As Point = MyBase.DataGridView.CurrentCellAddress
If ((currentCellAddress.X = e.ColumnIndex) AndAlso (currentCellAddress.Y = e.RowIndex)) AndAlso (e.Button = MouseButtons.Left) Then
If (Me.flagsState And 1) <> 0 Then
Me.flagsState = CByte(Me.flagsState And -2)
ElseIf MyBase.DataGridView.EditMode <> DataGridViewEditMode.EditProgrammatically Then
MyBase.DataGridView.BeginEdit(False)
End If
End If
End If
End Sub
Public Overrides Function KeyEntersEditMode(e As KeyEventArgs) As Boolean
Return (((((Char.IsLetterOrDigit(CChar(ChrW(CUShort(e.KeyCode)))) AndAlso ((e.KeyCode < Keys.F1) OrElse (e.KeyCode > Keys.F24))) OrElse ((e.KeyCode >= Keys.NumPad0) AndAlso (e.KeyCode <= Keys.Divide))) OrElse (((e.KeyCode >= Keys.OemSemicolon) AndAlso (e.KeyCode <= Keys.OemBackslash)) OrElse ((e.KeyCode = Keys.Space) AndAlso Not e.Shift))) AndAlso (Not e.Alt AndAlso Not e.Control)) OrElse MyBase.KeyEntersEditMode(e))
End Function
#End Region
End Class
Public Class DataGridViewRichTextBoxEditingControl
Inherits RichTextBox
Implements IDataGridViewEditingControl
Private _dataGridView As DataGridView
Private _rowIndex As Integer
Private _valueChanged As Boolean
Public Sub New()
Me.BorderStyle = BorderStyle.None
End Sub
Protected Overrides Sub OnTextChanged(e As EventArgs)
MyBase.OnTextChanged(e)
_valueChanged = True
EditingControlDataGridView.NotifyCurrentCellDirty(True)
End Sub
Protected Overrides Function IsInputKey(keyData As Keys) As Boolean
Dim keys__1 As Keys = keyData And Keys.KeyCode
If keys__1 = Keys.[Return] Then
Return Me.Multiline
End If
Return MyBase.IsInputKey(keyData)
End Function
Protected Overrides Sub OnKeyDown(e As KeyEventArgs)
MyBase.OnKeyDown(e)
If e.Control Then
Select Case e.KeyCode
Case Keys.B
If Me.SelectionFont.Bold Then
Me.SelectionFont = New Font(Me.Font.FontFamily, Me.Font.Size, Not FontStyle.Bold And Me.Font.Style)
Else
Me.SelectionFont = New Font(Me.Font.FontFamily, Me.Font.Size, FontStyle.Bold Or Me.Font.Style)
End If
Exit Select
Case Keys.U
If Me.SelectionFont.Underline Then
Me.SelectionFont = New Font(Me.Font.FontFamily, Me.Font.Size, Not FontStyle.Underline And Me.Font.Style)
Else
Me.SelectionFont = New Font(Me.Font.FontFamily, Me.Font.Size, FontStyle.Underline Or Me.Font.Style)
End If
Exit Select
Case Else
Exit Select
End Select
End If
End Sub
#Region "IDataGridViewEditingControl Members"
Public Sub ApplyCellStyleToEditingControl(dataGridViewCellStyle As DataGridViewCellStyle)
Me.Font = dataGridViewCellStyle.Font
End Sub
Public Property EditingControlDataGridView() As DataGridView
Get
Return _dataGridView
End Get
Set(value As DataGridView)
_dataGridView = value
End Set
End Property
Public Property EditingControlFormattedValue() As Object
Get
Return Me.Rtf
End Get
Set(value As Object)
If TypeOf value Is String Then
Me.Text = TryCast(value, String)
End If
End Set
End Property
Public Property EditingControlRowIndex() As Integer
Get
Return _rowIndex
End Get
Set(value As Integer)
_rowIndex = value
End Set
End Property
Public Property EditingControlValueChanged() As Boolean
Get
Return _valueChanged
End Get
Set(value As Boolean)
_valueChanged = value
End Set
End Property
Public Function EditingControlWantsInputKey(keyData As Keys, dataGridViewWantsInputKey As Boolean) As Boolean
Select Case (keyData And Keys.KeyCode)
Case Keys.[Return]
If (((keyData And (Keys.Alt Or Keys.Control Or Keys.Shift)) = Keys.Shift) AndAlso Me.Multiline) Then
Return True
End If
Exit Select
Case Keys.Left, Keys.Right, Keys.Up, Keys.Down
Return True
End Select
Return Not dataGridViewWantsInputKey
End Function
Public ReadOnly Property EditingPanelCursor() As Cursor
Get
Return Me.Cursor
End Get
End Property
Public Function GetEditingControlFormattedValue(context As DataGridViewDataErrorContexts) As Object
Return Me.Rtf
End Function
Public Sub PrepareEditingControlForEdit(selectAll As Boolean)
End Sub
Public ReadOnly Property RepositionEditingControlOnValueChange() As Boolean
Get
Return False
End Get
End Property
#End Region
Public Sub ApplyCellStyleToEditingControl1(dataGridViewCellStyle As DataGridViewCellStyle) Implements IDataGridViewEditingControl.ApplyCellStyleToEditingControl
End Sub
Public Property EditingControlDataGridView1 As DataGridView Implements IDataGridViewEditingControl.EditingControlDataGridView
Public Property EditingControlFormattedValue1 As Object Implements IDataGridViewEditingControl.EditingControlFormattedValue
Public Property EditingControlRowIndex1 As Integer Implements IDataGridViewEditingControl.EditingControlRowIndex
Public Property EditingControlValueChanged1 As Boolean Implements IDataGridViewEditingControl.EditingControlValueChanged
Public Function EditingControlWantsInputKey1(keyData As Keys, dataGridViewWantsInputKey As Boolean) As Boolean Implements IDataGridViewEditingControl.EditingControlWantsInputKey
End Function
Public ReadOnly Property EditingPanelCursor1 As Cursor Implements IDataGridViewEditingControl.EditingPanelCursor
Get
End Get
End Property
Public Function GetEditingControlFormattedValue1(context As DataGridViewDataErrorContexts) As Object Implements IDataGridViewEditingControl.GetEditingControlFormattedValue
End Function
Public Sub PrepareEditingControlForEdit1(selectAll As Boolean) Implements IDataGridViewEditingControl.PrepareEditingControlForEdit
End Sub
Public ReadOnly Property RepositionEditingControlOnValueChange1 As Boolean Implements IDataGridViewEditingControl.RepositionEditingControlOnValueChange
Get
End Get
End Property
End Class
RichTextBoxPrinter code
Imports System.Drawing.Printing
Imports System.Runtime.InteropServices
Public Class RichTextBoxPrinter
Private Const anInch As Double = 14.4
<StructLayout(LayoutKind.Sequential)> _
Private Structure RECT
Public Left As Integer
Public Top As Integer
Public Right As Integer
Public Bottom As Integer
End Structure
<StructLayout(LayoutKind.Sequential)> _
Private Structure CHARRANGE
Public cpMin As Integer
Public cpMax As Integer
End Structure
<StructLayout(LayoutKind.Sequential)> _
Private Structure FORMATRANGE
Public hdc As IntPtr
Public hdcTarget As IntPtr
Public rc As RECT
Public rcPage As RECT
Public chrg As CHARRANGE
End Structure
Private Const WM_USER As Integer = &H400
Private Const EM_FORMATRANGE As Integer = WM_USER + 57
<DllImport("USER32.dll")> _
Private Shared Function SendMessage(hWnd As IntPtr, msg As Integer, wp As IntPtr, lp As IntPtr) As IntPtr
End Function
Public Shared Function Print(richTextBoxHandle As IntPtr, charFrom As Integer, charTo As Integer, e As PrintPageEventArgs) As Integer
Dim rectToPrint As RECT
rectToPrint.Top = CInt(e.MarginBounds.Top * anInch)
rectToPrint.Bottom = CInt(e.MarginBounds.Bottom * anInch)
rectToPrint.Left = CInt(e.MarginBounds.Left * anInch)
rectToPrint.Right = CInt(e.MarginBounds.Right * anInch)
Dim rectPage As RECT
rectPage.Top = CInt(e.PageBounds.Top * anInch)
rectPage.Bottom = CInt(e.PageBounds.Bottom * anInch)
rectPage.Left = CInt(e.PageBounds.Left * anInch)
rectPage.Right = CInt(e.PageBounds.Right * anInch)
Dim hdc As IntPtr = e.Graphics.GetHdc()
Dim fmtRange As FORMATRANGE
fmtRange.chrg.cpMax = charTo
fmtRange.chrg.cpMin = charFrom
fmtRange.hdc = hdc
fmtRange.hdcTarget = hdc
fmtRange.rc = rectToPrint
fmtRange.rcPage = rectPage
Dim res As IntPtr = IntPtr.Zero
Dim wparam As IntPtr = IntPtr.Zero
wparam = New IntPtr(1)
Dim lparam As IntPtr = IntPtr.Zero
lparam = Marshal.AllocCoTaskMem(Marshal.SizeOf(fmtRange))
Marshal.StructureToPtr(fmtRange, lparam, False)
res = SendMessage(richTextBoxHandle, EM_FORMATRANGE, wparam, lparam)
Marshal.FreeCoTaskMem(lparam)
e.Graphics.ReleaseHdc(hdc)
Return res.ToInt32()
End Function
Public Shared Function Print(ctl As RichTextBox, width As Integer, height As Integer) As Image
Dim img As Image = New Bitmap(width, height)
Dim scale As Single
Using g As Graphics = Graphics.FromImage(img)
scale = CSng(width * 100) / img.HorizontalResolution
width = CInt(scale)
scale = CSng(height * 100) / img.VerticalResolution
height = CInt(scale)
Dim marginBounds As New Rectangle(0, 0, width, height)
Dim pageBounds As New Rectangle(0, 0, width, height)
Dim args As New PrintPageEventArgs(g, marginBounds, pageBounds, Nothing)
Print(ctl.Handle, 0, ctl.Text.Length, args)
End Using
Return img
End Function
End Class
I translated the dataGridViewRichTexBox and RichTextBoxPrinter from c# by this article
RichTextBox Cell in a DataGridView[
^]
I have not checked all the classes, then probably if someone tries to edit the cells, some errors may arise.
For me it's also difficult to understand all, i'm beginner, i just translated, but don't understand most of the code.
I notice that when i give a richtTextBox.Rtf value to the typed DataGridView cell, is correctly displayed, but if i bind the richTextBox.Rtf value through a DataTable, seems that the dataTable is not able to properly manage the value.
I think it depend from the dataTable.columns.DataType property.
From my (beginner) point of view the easiest way to solve is to override the DataTable.Columns.DataType property, but it's not overridable.
Other way is to check if there is an event when the DataTable pass the data to the DataGridView, or when the dataGridView obtain the data from the dataTable, but seems to be there is no such type of events.
These are 2 articles that can give an help
How to Manually Create a Typed DataTable[
^]
Converting Text to RichTextFormat[
^]
But i need an help.
I try to understand something.
I notice that if the DataGridView is bind from the DataTable, the DataGridViewImageCell.Paint method is not called.
I don't know which is the called method for paint the cells.
I added some code at the form:
Imports System.ComponentModel
Public Class Form1
Private dt As DataTable
Private dgv As DataGridView
Private b_Rtb_Dgv, b_Dt_Dgv As Button
Private rbRtb, rbDt As RadioButton
Private rtb As RichTextBox
Private iB As PictureBox
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.Size = New Size(650, 380)
Me.Location = New Point(0, 0)
Me.Text = "Form1"
rbRtb = New RadioButton
With rbRtb
.Size = New Size(100, 30)
.Location = New Point(10, 10)
.Text = "RichTextBox"
.Checked = True
AddHandler .Click, AddressOf rb_Click
End With
Me.Controls.Add(rbRtb)
rbDt = New RadioButton
With rbDt
.Size = New Size(100, 30)
.Location = New Point(10, 40)
.Text = "DataTable"
.Checked = False
AddHandler .Click, AddressOf rb_Click
End With
Me.Controls.Add(rbDt)
dt = New DataTable
With dt
.Columns.Add("col1", GetType(String))
.Rows.Add()
End With
dgv = New DataGridView
With dgv
.AllowUserToAddRows = False
.AllowUserToDeleteRows = False
.AllowUserToResizeColumns = False
.AllowUserToResizeRows = False
.ColumnHeadersVisible = False
.RowHeadersVisible = False
.RowsDefaultCellStyle.WrapMode = DataGridViewTriState.True
.Size = New Size(300, 100)
.Location = New Point(10, 80)
.RowTemplate.Height = .Size.Height
loadDgv()
AddHandler .CellPainting, AddressOf dgv_CellPainting
End With
Me.Controls.Add(dgv)
b_Rtb_Dgv = New Button
With b_Rtb_Dgv
.Size = New Size(200, 23)
.Location = New Point(110, 10)
.Text = "RichTextBox --> DataGridView"
AddHandler .Click, AddressOf b_Rtb_Dgv_Click
.Enabled = True
End With
Me.Controls.Add(b_Rtb_Dgv)
b_Dt_Dgv = New Button
With b_Dt_Dgv
.Size = New Size(200, 23)
.Location = New Point(110, 40)
.Text = "DataTable --> DataGridView"
AddHandler .Click, AddressOf b_Dt_Dgv_Click
.Enabled = False
End With
Me.Controls.Add(b_Dt_Dgv)
rtb = New RichTextBox
With rtb
.Size = New Size(300, 120)
.Location = New Point(10, 200)
.Rtf = "{\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fnil\fcharset0 Calibri;}} \viewkind4\uc1\pard\sa200\sl276\slmult1\lang16\b\f0\fs36 Donald\b0\fs22\par \i Duck\i0\par } "
End With
Me.Controls.Add(rtb)
iB = New PictureBox
With iB
.Size = New Size(150, 150)
.Location = New Point(350, 10)
.BackColor = Color.Snow
End With
Me.Controls.Add(iB)
End Sub
Private Sub loadDgv()
With dgv
Select Case rbRtb.Checked
Case True
.DataSource = Nothing
.AutoGenerateColumns = False
.Rows.Clear()
.Columns.Clear()
.Columns.Add(New DataGridViewRichTextBoxColumn)
.Rows.Add(New DataGridViewRichTextBoxCell)
Case False
If .AutoGenerateColumns = False Then
.Rows.Clear()
.Columns.Clear()
.AutoGenerateColumns = True
.DataSource = dt
End If
.Refresh()
End Select
.Columns.Item(0).Width = .Size.Width - 3
End With
End Sub
Private Sub rb_Click()
Select Case rbRtb.Checked
Case True
If b_Rtb_Dgv.Enabled = False Then b_Rtb_Dgv.Enabled = True : b_Dt_Dgv.Enabled = False
Case False
If b_Dt_Dgv.Enabled = False Then b_Dt_Dgv.Enabled = True : b_Rtb_Dgv.Enabled = False
End Select
loadDgv()
End Sub
Public Shared Function TextToRTF(ByVal RTFtext As String) As String
Dim data_object As New DataObject
data_object.SetData(DataFormats.Rtf, RTFtext)
Return data_object.GetData(DataFormats.Rtf)
End Function
Private Sub b_Rtb_Dgv_Click(sender As Object, e As EventArgs)
Me.dgv.Rows(0).Cells(0).Value = Me.rtb.Rtf
End Sub
Private Sub b_Dt_Dgv_Click(sender As Object, e As EventArgs)
dt.Rows(0)(0) = Me.rtb.Rtf
rtb.Rtf = dt.Rows(0)(0)
End Sub
Private Sub dgv_CellPainting(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellPaintingEventArgs)
With dgv
With .Rows(e.RowIndex).Cells(e.ColumnIndex)
Dim img As Image = GetRtfImage(e.RowIndex, .Value, True)
If img IsNot Nothing Then
iB.Image = img
e.Graphics.DrawImage(img, dgv.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, False))
End If
End With
End With
End Sub
Public Function GetRtfImage(rowIndex As Integer, value As Object, selected As Boolean) As Image
Dim cellSize As Size = dgv.Rows(0).Cells(0).Size
Dim _editingControl As New RichTextBox()
If cellSize.Width < 1 OrElse cellSize.Height < 1 Then
Return Nothing
End If
Dim ctl As RichTextBox = Nothing
If ctl Is Nothing Then
ctl = _editingControl
ctl.Size = cellSize
Try
ctl.Rtf = Convert.ToString(value)
Catch ex As Exception
End Try
End If
If ctl IsNot Nothing Then
Dim imgSize As New Size(cellSize.Width - 1, cellSize.Height - 1)
Dim rtfImg As Image = Nothing
If selected Then
ctl.BackColor = dgv.DefaultCellStyle.SelectionBackColor
ctl.ForeColor = dgv.DefaultCellStyle.SelectionForeColor
rtfImg = RichTextBoxPrinter.Print(ctl, imgSize.Width, imgSize.Height)
ctl.BackColor = dgv.DefaultCellStyle.BackColor
ctl.ForeColor = dgv.DefaultCellStyle.ForeColor
Else
rtfImg = RichTextBoxPrinter.Print(ctl, imgSize.Width, imgSize.Height)
End If
Return rtfImg
End If
Return Nothing
End Function
End Class
Added a PictureBox for see what happen to the image of the cell at the DataGridViewCellPainting Event.
Seems that the image is correctly stored in the dataGridView Cell, but something goes wrong with the painting method.