如何在不丢失链接的情况下将 WPF RichTextBox 保存在数据库中?

How can I save WPF RichTextBox in databse without lost links?

我在 Richtextbox 中有一个 Link,它运行良好,但如果我将该 Richtextbox 保存到数据库中,然后加载它,link 将被删除,我只能看到它的文本Link

例如我的 Richtextbox 有底部文本:

This is a link

但是保存并再次加载后我只能看到文本:

这是一个link

从选定文本动态创建的 hyperlink 如下:

            RichTextBox.IsDocumentEnabled = true;

            RichTextBox.IsReadOnly = true;

            Run run = new Run(RichTextBox.Selection.Text);
            Hyperlink hyp = new Hyperlink(run) { TargetName = run.Text };
            TERM.WordMain main = new TERM.WordMain();

            hyp.Click += new RoutedEventHandler(main.hyperLink_Click);
            hyp.NavigateUri = new Uri("http://search.msn.com");
            RichTextBox.Cut();

            var container = new InlineUIContainer(new TextBlock(hyp), RichTextBox.Selection.Start);
            RichTextBox.IsDocumentEnabled = true;
            RichTextBox.IsReadOnly = false;

将 richtextbox 内容作为 RTF 格式保存到文本字段:

 public static string ToStringFromBytes(System.Windows.Controls.RichTextBox richTextBox)
    {
        if (richTextBox.Document.Blocks.Count == 0)
        {
            return null;
        }

        MemoryStream memoryStream = new MemoryStream();

        TextRange textRange = new TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd);

        textRange.Save(memoryStream, System.Windows.DataFormats.Rtf);

        return Encoding.UTF8.GetString(memoryStream.ToArray());
    }

并从数据库加载到flowdocument

public static FlowDocument LoadFromString(string s)
    {
        try
        {
            byte[] byteArray = Encoding.UTF8.GetBytes(s);

            MemoryStream stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(s));

            FlowDocument doc = new FlowDocument();

            TextRange textRange = new TextRange(doc.ContentStart, doc.ContentEnd);

            textRange.Load(stream, System.Windows.DataFormats.Rtf);

            return doc;
        }
        catch (Exception ex)
        {
            throw;
        }
    }

以下示例似乎可以解决问题。

这里我加载并保存 XAML 而不是 rtf 格式的文本。另请注意,您需要在加载后将超链接的处理程序添加回元素,因为它们不会被序列化。

public partial class MainWindow : Window
{
    private const string _stateFile = "state.xaml";
    public MainWindow()
    {
        InitializeComponent();
        richTextBox.IsReadOnly = false;
    }

    private void createLinkButton_Click(object sender, RoutedEventArgs e)
    {
        richTextBox.IsDocumentEnabled = false;
        richTextBox.IsReadOnly = true;
        var textRange = richTextBox.Selection;
        var hyperlink = new Hyperlink(textRange.Start, textRange.End);
        hyperlink.TargetName = "value";
        hyperlink.NavigateUri = new Uri("http://search.msn.com");
        hyperlink.RequestNavigate += HyperlinkOnRequestNavigate;
        richTextBox.IsDocumentEnabled = true;
        richTextBox.IsReadOnly = false;
    }

    private void HyperlinkOnRequestNavigate(object sender,
        RequestNavigateEventArgs args)
    {
        // Outputs: "Requesting: http://search.msn.com, target=value" 
        Console.WriteLine("Requesting: {0}, target={1}", args.Uri, args.Target);
    }

    private void SaveXamlPackage(string filePath)
    {
        var range = new TextRange(richTextBox.Document.ContentStart,
            richTextBox.Document.ContentEnd);
        var fStream = new FileStream(filePath, FileMode.Create);
        range.Save(fStream, DataFormats.XamlPackage);
        fStream.Close();
    }

    void LoadXamlPackage(string filePath)
    {
        if (File.Exists(filePath))
        {
            var range = new TextRange(richTextBox.Document.ContentStart,
                richTextBox.Document.ContentEnd);
            var fStream = new FileStream(filePath, FileMode.OpenOrCreate);
            range.Load(fStream, DataFormats.XamlPackage);
            fStream.Close();
        }

        // Reapply event handling to hyperlinks after loading, since these are not saved:
        foreach (var paragraph in richTextBox.Document.Blocks.OfType<Paragraph>())
        {
            foreach (var hyperlink in paragraph.Inlines.OfType<Hyperlink>())
            {
                hyperlink.RequestNavigate += HyperlinkOnRequestNavigate;
            }
        }
    }

    private void saveButton_Click(object sender, RoutedEventArgs e)
    {
        SaveXamlPackage(_stateFile);
    }

    private void loadButton_Click(object sender, RoutedEventArgs e)
    {
        LoadXamlPackage(_stateFile);
    }
}