如何比较两个flowdocument

本文关键字:flowdocument 两个 比较 何比较 | 更新日期: 2023-09-27 18:16:33

我想比较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为包含FlowDocument xml内容的字符串

如何比较两个flowdocument

假设您的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,所以可以将XAML解析为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);
}

如果您担心可能有嵌入的消息,并希望在这种情况下生成警告消息,请参见查找FlowDocument中的所有图像。