检测RichTextBox是否为空

时间:2011-04-28 22:02:13

标签: wpf richtextbox flowdocument

检测WPF RichTextBox / FlowDocument是否为空的最佳方法是什么?

如果文档中只有文本,则以下内容有效。如果它包含UIElement的

,则不是
new TextRange(Document.ContentStart, Document.ContentEnd).IsEmpty

5 个答案:

答案 0 :(得分:14)

您可以比较指针,这不太可靠:

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

如果已加载RTB,则评估为2;如果已输入并再次删除内容,则评估为4
如果RTB被完全清除,例如通过select all -> delete,该值将为0


Silverlight reference on MSDN中找到了另一种可以改编和改进的方法:

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

答案 1 :(得分:3)

如果您需要区分图像和空白,那么H.B。的答案并不有用。您可以使用this answer之类的内容来检查图像。

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

这似乎很费力,但对于所有场景来说仍然可能并不正确。但我无法找到更好的方法。

答案 2 :(得分:2)

如果您没有在RTB中添加任何内容,则上述答案有效。但是,如果您只是删除内容,RTB往往会返回一个空段,而不是一个完全空的字符串。因此,在这种情况下,这更可靠:

string text = new TextRange(Document.ContentStart, Document.ContentEnd).Text;
return !String.IsNullOrWhiteSpace(text);

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

答案 3 :(得分: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

可能还有其他检查要做,但这至少包括文字,图片和表格。

答案 4 :(得分: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作为基线。

如果没有文字字符,长度检查可能会很昂贵,但是它们粘贴在海量图像中。