簡體   English   中英

如何在 WPF 數據網格中呈現 HTML 或 markdown?

[英]How can I render HTML or markdown in a WPF datagrid?

有沒有辦法在 .NET Core WPF Datagrid 列/單元格中渲染/顯示 HTML(或 Markdown)?

我在數據庫中有一些文本,我想向其中添加一些格式選項。 我正在考慮添加使用 markdown 對其進行格式化的可能性。

然后,此文本使用itemsource = List<myobject>顯示在數據網格中,我希望將其格式化顯示在數據網格列/單元格中。

所以我使用Markdig從數據庫中的文本生成HTML。 這給了我類似的東西:

<p>This is a text with some <em>emphasis</em></p>

這應該顯示為:

這是一個有一定重點的文字

但后來我卡住了。 HTML 似乎與 WPF 不同。

可以使用 DataGridTemplateColumn 中的 WPF 的WebBrowser 控件來執行此操作。 一些示例代碼如下。

要讓 WebBrowser 顯示 HTML 字符串,您必須調用 NavigateToString。 我已經使用附加屬性完成了此操作,如另一個 Stack Overflow 答案中所述。

我還做了一些工作來刪除控件默認放置在單元格中的禁用滾動條,即使內容適合。 我已經使用 CSS 樣式來做到這一點,但它有點 hacky。

請注意,我們被警告說,WebBrowser 控件在 memory 的使用方面非常重要,因此您可能不希望在有很多行的網格中這樣做。

在此處輸入圖像描述

C#:

using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;

namespace WpfApp14
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.CreateProducts();
            this.MyDataGrid.ItemsSource = Products;
        }

        public ObservableCollection<Product> Products { get; set; }

        private void CreateProducts()
        {
            Products = new ObservableCollection<Product>
            {
                new Product{ID = 1, Html = "HTML with no formatting"},
                new Product{ID = 2, Html= "<h1>This is a <i>test</i> header</h1>"},
                new Product{ID = 3, Html="<p>This is a text with some <em>emphasis</em></p>"},
                new Product{ID = 4, Html="<ul><li>Product 1</li><li>Product 2</li><li>Product 3</li></ul>"}
            };
        }
    }

    public class Product : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private int id;
        public int ID
        {
            get { return id; }
            set
            {
                id = value;
                PropertyChanged?.Invoke(this,
                   new PropertyChangedEventArgs(nameof(ID)));
            }
        }

        private string html;
        public string Html
        {
            get { return html; }
            set
            {
                html = RemoveScrollbars(value);
                PropertyChanged?.Invoke(this,
                    new PropertyChangedEventArgs(nameof(Html)));
            }
        }

        private string RemoveScrollbars(string html)
        {
            string before = "<head><style>body{overflow:hidden;}</style></head><body>";
            string after = "</body>";
            return before + html + after;
        }
    }

    public static class BrowserBehavior
    {
        public static readonly DependencyProperty HtmlProperty = DependencyProperty.RegisterAttached(
            "Html",
            typeof(string),
            typeof(BrowserBehavior),
            new FrameworkPropertyMetadata(OnHtmlChanged));

        [AttachedPropertyBrowsableForType(typeof(WebBrowser))]
        public static string GetHtml(WebBrowser d)
        {
            return (string)d.GetValue(HtmlProperty);
        }

        public static void SetHtml(WebBrowser d, string value)
        {
            d.SetValue(HtmlProperty, value);
        }

        static void OnHtmlChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            WebBrowser wb = d as WebBrowser;
            if (wb != null)
                wb.NavigateToString(e.NewValue as string);
        }
    }
}

XAML:

<Window x:Class="WpfApp14.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp14"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <DataGrid x:Name="MyDataGrid" AutoGenerateColumns="False" CanUserAddRows="False">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding ID}"/>
            <DataGridTemplateColumn Width="300">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <WebBrowser local:BrowserBehavior.Html="{Binding Html}" Height="90"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>
</Window>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM