检测一个RichTextBox是否为空

12
什么是检测WPF RichTextBox/FlowDocument是否为空的最佳方法?
如果文档中仅包含文本,则以下内容有效。如果包含UIElement,则无效。
new TextRange(Document.ContentStart, Document.ContentEnd).IsEmpty
5个回答

14

你可以比较指针,但这并不是非常可靠的:

var start = rtb.Document.ContentStart;
var end = rtb.Document.ContentEnd;
int difference = start.GetOffsetToPosition(end);

如果 RTB 已加载,则此值将计算为 2,如果输入了内容并再次删除,则为 4
如果 RTB 完全清除(例如使用 选择全部 -> 删除),则该值将为 0


MSDN 上的 Silverlight 参考文档 中发现了另一种方法,可以进行改进和适应:

public bool IsRichTextBoxEmpty(RichTextBox rtb)
{
    if (rtb.Document.Blocks.Count == 0) return true;
    TextPointer startPointer = rtb.Document.ContentStart.GetNextInsertionPosition(LogicalDirection.Forward);
    TextPointer endPointer = rtb.Document.ContentEnd.GetNextInsertionPosition(LogicalDirection.Backward);
    return startPointer.CompareTo(endPointer) == 0;
}

即使 RichTextBox 是空的,计数也为一。 - Benoit Dion
我编辑了我的答案,展示了另一种方法,但有点奇怪。 - H.B.
前三行对我有用。谢谢!即使只剩下一个空格,你也不会得到0的差异。 - sm2mafaz
我本希望最终得到的是类似于 empty== count<=4 的结果,但遗憾的是,如果你将图像粘贴到一个刚清空的 rtb 中,它会产生 3。 - Bill Tarbell

3
如果您需要区分图像和空格,H.B.的答案并不实用。您可以使用类似这个答案来检查图像。
bool IsEmpty(Document document)
{
    string text = new TextRange(Document.ContentStart, Document.ContentEnd).Text;
    if (string.IsNullOrWhiteSpace(text) == false)
        return false;
    else
    {
        if (document.Blocks.OfType<BlockUIContainer>()
            .Select(c => c.Child).OfType<Image>()
            .Any())
        return false;
    }
    return true;
}

这似乎很费力,而且可能仍然不适用于所有情况。但我找不到更好的方法。

这非常昂贵,因为它每次都将文档呈现为新字符串。 - Panagiotis Kanavos

2
上述答案在RTB中没有输入任何内容时有效。但是,如果您只是删除了内容,RTB通常会返回一个空的段落,而不是完全为空的字符串。因此,在这种情况下,以下方法更加可靠:
string text = new TextRange(Document.ContentStart, Document.ContentEnd).Text;
return !String.IsNullOrWhiteSpace(text);

这仅适用于文本内容,当然。

0
这是H.B.想法的延伸,适用于文本和图像

我发现当RTB有文本时,差异始终大于4。但是,如果您只粘贴图像,则为3。为了解决这个问题,我查看原始rtf字符串的字符串长度。

var start = Document.ContentStart;
var end = Document.ContentEnd;
var difference = start.GetOffsetToPosition(end);

HasText = difference > 4 || GetRtfText().Length > 350;


public string GetRtfText()
{
  var tr = new TextRange(Document.ContentStart, Document.ContentEnd);
  using (var ms = new MemoryStream())
  {
    tr.Save(ms, DataFormats.Rtf);
    return Encoding.Default.GetString(ms.ToArray());
  }
}

通过我的测试,我发现一个没有字符的空框的长度为270。即使我粘贴一个只有1像素大小的图像,它也会膨胀到406。

我尝试了打开各种格式选项而不输入任何字母,但都没有接近300,所以我选择了350作为基准。

如果没有文本字符,但他们粘贴了一个巨大的图像,则长度检查可能会很昂贵。


0

首先,感谢McGarnagle的回答,他们的答案让我朝着正确的方向前进。然而,由于某种原因,他们的图像检查对我不起作用。这就是我最终做的事情:

    Private Function RichTextBoxIsEmpty(BYVAL rtb As RichTextBox) As Boolean

    Dim ReturnCode As Boolean = True

    Dim text As String = New TextRange(rtb.Document.ContentStart, rtb.Document.ContentEnd).Text

    If String.IsNullOrWhiteSpace(text) Then

        For Each block As Block In rtb.Document.Blocks

            'check for an image
            If TypeOf block Is Paragraph Then
                Dim paragraph As Paragraph = DirectCast(block, Paragraph)
                For Each inline As Inline In paragraph.Inlines
                    If TypeOf inline Is InlineUIContainer Then
                        Dim uiContainer As InlineUIContainer = DirectCast(inline, InlineUIContainer)
                        If TypeOf uiContainer.Child Is Image Then
                            ReturnCode = False
                            Exit For
                        End If
                    End If
                Next
            End If

            ' Check for a table
            If TypeOf block Is Table Then
                ReturnCode = False
                Exit For
            End If

        Next

    Else

        ReturnCode = False

    End If

    Return ReturnCode

End Function

可能还有其他检查要做,但至少这涵盖了文本、图像和表格。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接