我设置了一个WPF文本块,其属性为TextWrapping =“Wrap”。
当我在开头传入一个带有制表符(我的情况下是vbTab)的长字符串时,我希望包装符合这一点并保持字符串的包裹部分缩进。 例如,而不是:
[vbTab] thisisreallylong
andwrapped
我想要
[vbTab] thisisreallylong
[vbTab] andwrapped
,理想情况下也适用于多个标签等。
[编辑 - 其他详细信息]
因为文本块的大小可变,并且包含多行文本以及各种缩进量,所以我不能只有一个边距或手动拆分字符串并添加标签。
基本上我想要的是它处理像段落一样的文本行,在它们换行时保持缩进。
答案 0 :(得分:4)
根据您的想法,我能够提出这个解决方案
我会将每行开头的所有标签转换为每个0.5英寸的边距,并在段落中添加相同的文字并将计算的边距应用于相同的
TextBlock是不可行的,因为它对于运行粗体,内联ui容器等基本文本内联很有用。在TextBlock中添加段落更复杂,所以我根据FlowDocument制作了解决方案。
<强>结果强>
以下示例使用FlowDocumentScrollViewer
或RichTextBox
或FlowDocumentReader
或普通FlowDocument
我已经使用附加属性创建了解决方案,因此您可以将其附加到任何提到的内容,甚至可以为文档添加自己的主机。您只需将IndentationProvider.Text
设置为所需的主机即可。
<强> 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">	this is really long and wrapped
		another line this is also really long and wrapped
	one more line this is also really long and wrapped
another line this is also really long and wrapped
		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>
	
指的是tab char
<强> 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
<强>演示强>