检测WPF RichTextBox / FlowDocument是否为空的最佳方法是什么?
如果文档中只有文本,则以下内容有效。如果它包含UIElement的
,则不是new TextRange(Document.ContentStart, Document.ContentEnd).IsEmpty
答案 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)
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作为基线。
如果没有文字字符,长度检查可能会很昂贵,但是它们粘贴在海量图像中。