2014-08-27 1 views
1

J'ai un bloc de texte WPF mis en place avec la propriété TextWrapping = "Wrap". Quand je passe une longue chaîne avec un caractère de tabulation (vbTab dans mon cas) au début, je voudrais que l'emballage honore cela et garde les parties enveloppées de la chaîne en retrait. Par exemple, au lieu de:Préservation de l'indentation lors de l'encapsulation dans un contrôle de bloc de texte wpf

[vbTab] thisisreallylong

andwrapped

Je veux

[vbTab] thisisreallylong

[vbTab] andwrapped

et idéalement pour plusieurs onglets, etc.

[modifier - détails supplémentaires]

Parce que le textblock sera de taille variable et contiennent plusieurs lignes de texte avec différentes quantités de indenter, je ne peux pas avoir juste une marge ou manuellement diviser les chaînes et ajouter des onglets. Essentiellement, ce que je veux, c'est qu'il traite les lignes de texte comme des paragraphes, qui gardent leur retrait quand ils s'enroulent.

+0

S'il y a effectivement un onglet dans la chaîne, pourrait gifler 'xml: space = « conserver »' sur votre TextBlock, sinon si vous voulez juste que tout avoir un espace à gauche, peut-être juste une gauche 'marge 'sur ce serait accomplir le visuel que vous recherchez? –

+0

Le problème n'est pas de préserver les onglets, ils s'affichent bien - il conserve la ligne indentée lorsque le texte recouvre plusieurs lignes. Au moment où la deuxième ligne (etc.) du texte encapsulé est à nouveau contre le bord gauche. – simonalexander2005

+0

vous pouvez avoir besoin de marge ici, les onglets peuvent ne pas être réalisables. – pushpraj

Répondre

4

Sur la base de votre idée, je suis en mesure de trouver cette solution

Je vais convertir tous les onglets en début de chaque ligne à la marge 0,5 pouces chacun et ajoutera le même texte dans un paragraphe et appliquer la marge calculée à la même

Un TextBlock n'était pas réalisable pour la même chose car il est utile pour les lignes de texte de base comme le gras, le conteneur en ligne, etc. L'ajout de paragraphe était plus compliqué dans un TextBlock alors j'ai fait la solution basé sur FlowDocument.

Résultat

result

exemple ci-dessous montrent la même chose en utilisant FlowDocumentScrollViewer ou RichTextBox ou FlowDocumentReader ou plaine FlowDocument

J'ai créé la solution en utilisant les propriétés ci-joints, de sorte que vous pouvez attacher la même chose l'un des mentionnés ou même ajouter votre propre hôte pour le document. vous devez simplement régler IndentationProvider.Text sur l'hôte souhaité.

XAML

<Window x:Class="MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:sys="clr-namespace:System;assembly=mscorlib" 
     xmlns:l="clr-namespace:PreservingIndentationDemo" 
     Title="MainWindow" 
     Height="350" 
     Width="525"> 
    <Window.Resources> 
     <sys:String x:Key="longString" 
        xml:space="preserve">&#x09;this is really long and wrapped 

&#x09;&#x09;another line this is also really long and wrapped 

&#x09;one more line this is also really long and wrapped 

another line this is also really long and wrapped 

&#x09;&#x09;another line this is also really long and wrapped 
     </sys:String> 
    </Window.Resources> 
    <Grid> 
     <FlowDocumentScrollViewer l:IndentationProvider.Text="{StaticResource longString}" /> 
     <!--<RichTextBox l:TextToParaHelper.Text="{StaticResource longString}" IsReadOnly="True"/>--> 
     <!--<FlowDocumentReader l:TextToParaHelper.Text="{StaticResource longString}" />--> 
     <!--<FlowDocument l:TextToParaHelper.Text="{StaticResource longString}" />--> 
    </Grid> 
</Window> 

&#x09; fait référence à l'onglet ombles

IndentationProvider

Class IndentationProvider 

    Public Shared Function GetText(obj As DependencyObject) As String 
     Return DirectCast(obj.GetValue(TextProperty), String) 
    End Function 

    Public Shared Sub SetText(obj As DependencyObject, value As String) 
     obj.SetValue(TextProperty, value) 
    End Sub 

    ' Using a DependencyProperty as the backing store for Text. This enables animation, styling, binding, etc... 
    Public Shared ReadOnly TextProperty As DependencyProperty = DependencyProperty.RegisterAttached("Text", GetType(String), GetType(IndentationProvider), New PropertyMetadata(Nothing, AddressOf OnTextChanged)) 

    Private Shared Sub OnTextChanged(d As DependencyObject, e As DependencyPropertyChangedEventArgs) 
     Dim blocks As BlockCollection = Nothing 

     Dim rtb As RichTextBox = TryCast(d, RichTextBox) 
     If rtb IsNot Nothing Then 
      rtb.Document.Blocks.Clear() 
      blocks = rtb.Document.Blocks 
     End If 

     If blocks Is Nothing Then 
      Dim fd As FlowDocument = TryCast(d, FlowDocument) 
      If fd IsNot Nothing Then 
       fd.Blocks.Clear() 
       blocks = fd.Blocks 
      End If 
     End If 

     If blocks Is Nothing Then 
      Dim fdr As FlowDocumentReader = TryCast(d, FlowDocumentReader) 
      If fdr IsNot Nothing Then 
       fdr.Document = New FlowDocument() 
       blocks = fdr.Document.Blocks 
      End If 
     End If 

     If blocks Is Nothing Then 
      Dim fdr As FlowDocumentScrollViewer = TryCast(d, FlowDocumentScrollViewer) 
      If fdr IsNot Nothing Then 
       fdr.Document = New FlowDocument() 
       blocks = fdr.Document.Blocks 
      End If 
     End If 

     Dim newValue As String = TryCast(e.NewValue, String) 
     If Not String.IsNullOrWhiteSpace(newValue) Then 
      For Each line As String In newValue.Split(ControlChars.Lf) 
       Dim leftMargin As Double = 0 
       Dim newLine As String = line 
       While newLine.Length > 0 AndAlso newLine(0) = ControlChars.Tab 
        leftMargin += 0.5 
        newLine = newLine.Remove(0, 1) 
       End While 
       Dim marginInch As String = leftMargin & "in" 
       Dim marginDip As Double = CDbl(New LengthConverter().ConvertFromString(marginInch)) 

       Dim para As New Paragraph(New Run(newLine)) With {.Margin = New Thickness(marginDip, 0, 0, 0)} 
       blocks.Add(para) 
      Next 
     End If 
    End Sub 
End Class 

Démo

essayer demo project

+0

Merci pour ça! vous y mettez beaucoup de travail – simonalexander2005

+0

Je dirais merci pour le défi et l'idée, j'ai aussi appris un nouveau truc. – pushpraj

Questions connexes