如何比较两个FlowDocuments?

时间:2015-10-07 16:48:45

标签: c# .net richtextbox flowdocument

我想将FlowDocumentRich Text Box的文档进行比较。这是代码

if (rtbEditor.Document != (XamlReader.Parse(currentNote.content) as FlowDocument))
{
   MessageBox.Show("Overwrite existing Note?", "Save", MessageBoxButton.OKCancel);
}

一开始我将rtbEditor的文档设置为

rtbEditor.Document = XamlReader.Parse(currentNote.content) as FlowDocument;

因此,除非rtbEditor的内容发生变化,否则我认为if语句不应该执行,但确实如此。可能这不是比较FlowDocuments的方法。如果这不是正确的方法,那么我们如何比较两个文件?

如果有必要,currentNote.content是包含xml内容FlowDocument的字符串。

1 个答案:

答案 0 :(得分:0)

假设您的FlowDocument实例中没有图像,您可以序列化为XAML并比较XAML。首先,创建扩展方法以生成XAML字符串:

public static class FrameworkContentElementExtensions
{
    public static string ToXaml(this FrameworkContentElement element) // For instance, a FlowDocument
    {
        if (element == null)
            return null;
        var sb = new StringBuilder();
        using (var xmlWriter = XmlWriter.Create(sb))
        {
            XamlWriter.Save(element, xmlWriter);
        }
        return sb.ToString();
    }

    public static string ToFormattedXamlString(this FrameworkContentElement element)
    {
        if (element == null)
            return null;
        var settings = new XmlWriterSettings() { Indent = true, IndentChars = "    " };
        var sb = new StringBuilder();
        using (var xmlWriter = XmlWriter.Create(sb, settings))
        {
            XamlWriter.Save(element, xmlWriter);
        }
        return sb.ToString();
    }
}

然后你可以做

if (rtbEditor.Document.ToXaml() != currentNote.content)
{
   MessageBox.Show("Overwrite existing Note?", "Save", MessageBoxButton.OKCancel);
}

请注意,如果XAML因化妆品格式(XML缩进)而不同,由于XAML文档是有效的XML,您可以parse your XAML to an XElement并使用XNode.DeepEquals()。您还可以将FrameworkContentElement直接序列化为XElement,而无需插入字符串表示,以提高性能:

public static class FrameworkContentElementExtensions
{
    public static XElement ToXamlXElement(this FrameworkContentElement element) // For instance, a FlowDocument
    {
        if (element == null)
            return null;
        var doc = new XDocument();
        using (var xmlWriter = doc.CreateWriter())
        {
            XamlWriter.Save(element, xmlWriter);
        }
        var xElement = doc.Root;
        if (xElement != null)
            xElement.Remove();
        return xElement;
    }
}

然后

var docXaml = rtbEditor.Document.ToXamlXElement();
var currentNoteXaml = XElement.Parse(currentNote.content);
if (!XNode.DeepEquals(docXaml, currentNoteXaml))
{
   MessageBox.Show("Overwrite existing Note?", "Save", MessageBoxButton.OKCancel);
}

如果您担心可能存在嵌入式消息,并且想要在这种情况下生成警告消息,请参阅Finding all Images in a FlowDocument