在C#桌面应用程序的DataGridView控件单元格中显示HTML

本文关键字:单元格 显示 HTML 控件 DataGridView 桌面 应用程序 | 更新日期: 2023-09-27 18:21:17

我有一个C#桌面应用程序,它连接到数据库并从数据库中填充DataGridView(使用数据绑定)。一列的值是HTML格式的值,应在DataGridView中显示为HTML。不幸的是,目前所有的内容(例如标签)都是以原始格式(即不是HTML格式)编写的。

我已经在网上找到了一个网站,上面已经有人问过这个问题。不幸的是,他们没有谈论绑定数据(或者至少我不明白还有什么可以做的…)

有人能给我一些提示吗?我已经使用ILSpy来了解如何完成这项工作,但这对我来说更困惑,而不是它的帮助。

在C#桌面应用程序的DataGridView控件单元格中显示HTML

派生了一个简化的解决方案,用于在数据网格视图中呈现html内容

解决方案使用WebBrowser渲染html,并将内容转换为位图,然后使用图形绘制到单元格中。

using System;
using System.Drawing;
using System.Windows.Forms;
namespace DataGridViewTest
{
internal class DataGridViewHtmlCell : DataGridViewTextBoxCell
{
    protected override void Paint(
        Graphics graphics,
        Rectangle clipBounds,
        Rectangle cellBounds,
        Int32 rowIndex,
        DataGridViewElementStates cellState,
        Object values,
        Object formattedValue,
        String errorText,
        System.Windows.Forms.DataGridViewCellStyle cellStyle,
        DataGridViewAdvancedBorderStyle advancedBorderStyle,
        DataGridViewPaintParts paintParts)
    {
        // add a condition here to check formattedValue is Html
        // you shall use HtmlAgilityPack to determine this.
        if(isHtml)
        {
            RenderHtmlValue(graphics, cellBounds, formattedValue, true);
        }
        else
        {
            base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, values, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
        }
    }   
    private Size RenderHtmlValue(
        Graphics graphics,
        Rectangle cellBounds,
        string formattedValue,
        bool drawCell)
    {
        using (var webBrowser = new WebBrowser())
        {
            webBrowser.ScrollBarsEnabled = false;
            webBrowser.Navigate("about:blank");
            webBrowser.Document.Write(formattedValue);
            webBrowser.Size = Size;
            var rect = new Rectangle(
                webBrowser.Document.Body.ScrollRectangle.Location,
                webBrowser.Document.Body.ScrollRectangle.Size);
            rect.Width = Size.Width - cellBounds.X;
            webBrowser.Size = rect.Size;
            cellBounds = new Rectangle(cellBounds.X, cellBounds.Y, rect.Width, rect.Height);
            var htmlBodyElement = webBrowser.Document.Body.DomElement as mshtml.IHTMLBodyElement;
            htmlBodyElement.WhenNotNull(
                bodyElement =>
                {
                    cellBounds.Height += Convert.ToInt32(htmlBodyElement.bottomMargin);
                });
            if(drawCell)
            {
                using (var bitmap = new Bitmap(webBrowser.Width, webBrowser.Height))
                {
                    webBrowser.DrawToBitmap(bitmap, targetBounds);
                    graphics.DrawImage(bitmap, location);
                }
            }
        }
        return cellBounds.Size;
    }
    protected override Size GetPreferredSize(
        Graphics graphics,
        System.Windows.Forms.DataGridViewCellStyle cellStyle,
        Int32 rowIndex,
        Size constraintSize)
    {
        return RenderHtmlValue(graphics, cellBounds, formattedValue, false);
    }
}

}