Каков наилучший способ определить, пустой ли WPF RichTextBox/FlowDocument?
Следующее работает, если в документе присутствует только текст. Нет, если он содержит
UIElement <new TextRange(Document.ContentStart, Document.ContentEnd).IsEmpty
Каков наилучший способ определить, пустой ли WPF RichTextBox/FlowDocument?
Следующее работает, если в документе присутствует только текст. Нет, если он содержит
UIElement <new TextRange(Document.ContentStart, Document.ContentEnd).IsEmpty
Вы можете сравнить указатели, которые не слишком надежны:
var start = rtb.Document.ContentStart;
var end = rtb.Document.ContentEnd;
int difference = start.GetOffsetToPosition(end);
Это оценивается до 2
, если загружается RTB, и 4
, если содержимое было снова введено и удалено.
Если RTB полностью очищен, например, через select all -> delete
значение будет 0
.
В ссылка Silverlight на 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;
}
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;
}
Это кажется трудоемким и, вероятно, не подходит для всех сценариев. Но я не мог найти лучшего способа.
Ответ выше работает, если вы ничего не вкладываете в RTB. Однако, если вы просто удаляете содержимое, RTB имеет тенденцию возвращать один, пустой абзац, а не полностью пустую строку. Таким образом, это более надежно в таких случаях:
string text = new TextRange(Document.ContentStart, Document.ContentEnd).Text;
return !String.IsNullOrWhiteSpace(text);
Это относится только к текстовому содержимому, конечно.
Сначала - спасибо МакГарнаглу - их ответ заставил меня идти в правильном направлении. Однако по какой-то причине их проверка изображения не сработала для меня. Это то, что я закончил:
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
могут быть другие проверки, но это, по крайней мере, охватывает текст, изображения и таблицы.
Здесь расширение H.B. идея, которая работает как с текстом, так и с изображениями.
Я обнаружил, что разница всегдa > 4, когда RTB имеет текст. Однако, если вы вставляете только изображение, то оно равно 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 для базовой линии.
Проверка длины может быть дорогой, если текстовых символов нет, но они были вставлены в массивное изображение.
if (textbox1->Text->Length == 0)
{
//Do ANYTHING
}