如何在没有丢失链接的数据库中保存WPF RichTextBox?

时间:2016-01-04 12:06:18

标签: c# wpf hyperlink richtextbox

我在Richtextbox中有一个链接并且它运行良好但是如果我将Richtextbox保存到数据库中,然后将其加载到要删除的链接,我只能看到该链接的文本

例如我的Richtextbox有底部文字:

This is a link

但是在保存并再次加载后我才能看到文字:

这是一个链接

从所选文本动态创建的超链接如下:

            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;

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

 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;
        }
    }

1 个答案:

答案 0 :(得分:4)

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

这里我加载并保存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);
    }
}