2011-04-28 42 views
11

¿Cuál es la mejor forma de detectar si un WPF RichTextBox/FlowDocument está vacío?Detectar si un RichTextBox está vacío

Lo siguiente funciona si solo el texto está presente en el documento. No si contiene de UIElement

new TextRange(Document.ContentStart, Document.ContentEnd).IsEmpty 

Respuesta

13

Se podría comparar los punteros, que no es muy fiable:

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

Esto se evalúa como 2 si se carga el RTB, y 4 si el contenido ha sido introducido y eliminado de nuevo.
Si el RTB está completamente despejado, p. a través de select all -> delete el valor será 0.


En el Silverlight reference on MSDN otro método se encuentra que puede ser adaptado y mejorado para:

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

El recuento es uno incluso si el RichTextBox está vacío. –

+0

Hmm, eso realmente tiene sentido ... –

+0

He editado mi respuesta para mostrar otro enfoque, aunque es un poco extraño. –

0

La respuesta anterior funciona si usted no pone nada en el RTB. Sin embargo, si simplemente elimina los contenidos, el RTB tiende a devolver un solo párrafo vacío, no una cadena completamente vacía. Por lo tanto, esto es más confiable en tales casos:

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

Esto solo se aplica a los contenidos textuales, por supuesto.

3

La respuesta de H.B. no es útil si necesita distinguir entre imágenes y espacios en blanco. Puede usar algo como this answer para buscar imágenes.

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

Esto parece laborioso, y probablemente aún no sea el correcto para todos los escenarios. Pero no pude encontrar una mejor manera.

0

Primero - gracias a McGarnagle - su respuesta me ayudó a ir en la dirección correcta. Sin embargo, por alguna razón, su verificación de imagen no funcionó para mí. Esto es lo que terminé haciendo:

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 

puede haber otros controles que hacer, pero esto al menos cubre texto, imágenes y tablas.

0

Aquí hay una extensión de la idea de H.B. que funciona tanto con el texto como con las imágenes.

Encontré que la diferencia siempre es> 4 cada vez que el RTB tiene texto. Sin embargo, si solo pegas una imagen es 3. Para combatir esto miro la longitud de la cadena de la cadena rtf en bruto.

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

A través de mis pruebas he encontrado que una caja vacía sin caracteres tiene una longitud de 270. Si i incluso pegar en una imagen que sólo 1 de píxeles de tamaño se hincha a 406.

jugaba con Alternar varias opciones de formato sin escribir ninguna letra y no se han acercado a 300, así que fui con 350 para la línea de base.

El control de longitud puede ser costoso si no hay caracteres de texto, pero se pegaron en una imagen masiva.

Cuestiones relacionadas