2011-04-19 21 views
5

当TextWrapping =“Wrap”时,WPF中是否有方法使文本格式化为文本框中显示的格式?WPF:从文本框中获取“包装”文本

<TextBox Width="200" 
      TextWrapping="Wrap"     
      VerticalScrollBarVisibility="Auto" 
      HorizontalScrollBarVisibility="Auto" /> 

我试着使用的TextFormatter类,但它ONTY让我绘制文本绘制上下文与包括换行符在那里我只需要文字。

+0

我很抱歉,但无法理解的问题,统计EMENT。是否要复制该文本框中的文本,并在其他位置粘贴时想保留被包装的位置? – publicgk 2011-04-19 18:35:03

+0

作为文字还是视觉/图像? – 2011-04-19 18:45:22

+0

@publicgk,我确切的情况是将文本传递给主动报告,同时保留包装的位置,所以我得到了与屏幕上显示的相同的包装。所以我需要它作为文本。 – Fbeauche 2011-04-19 18:54:25

回答

3

以下是如何获得明显换行符的完整文本。

注:

  • 包括从Advanced Text Formatting Example以下类项目中的:
    • CustomTextSource
    • FontRendering
    • GenericTextProperties
  • 有其在CustomTextSource提到的一些限制类。不过,我相信您的要求不受这些限制的影响。
  • 这些只是例子。您可能需要根据需要修改代码。
  • 该代码仍然使用黑客(虽然体面的) - InputTextBox.ViewportWidth。您可能需要根据需要测试最终输出是否为,确切地说是

见:Advanced Text FormattingAdvanced Text Formatting Example

示例代码
XAML:

<Window x:Class="TextFormatterForWrappedText.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <TextBox Width="200" 
      x:Name="InputTextBox" 
      TextWrapping="Wrap" 
      VerticalScrollBarVisibility="Auto" 
      HorizontalScrollBarVisibility="Auto" Margin="23,12,280,241" /> 
     <TextBox x:Name="FormattedDisplayTextBox" Height="172" 
       HorizontalAlignment="Left" VerticalAlignment="Top" 
       Margin="23,105,0,0" Width="438" AcceptsReturn="True" 
       TextWrapping="Wrap" /> 
     <Button HorizontalAlignment="Left" VerticalAlignment="Top" 
       Margin="257,12,0,0" Height="23" Content="Copy" 
       Name="CopyButton" Width="129" Click="CopyButton_Click" /> 
    </Grid> 
</Window> 

代码隐藏:

private void CopyButton_Click(object sender, RoutedEventArgs e) 
{ 
    List<string> stringList = GetTextAsStringList(); 
    StringBuilder sb = new StringBuilder(); 
    foreach (string s in stringList) 
    { 
     sb.Append(s); 
     sb.Append("\r\n"); 
    } 

    Clipboard.SetData(System.Windows.DataFormats.Text, sb.ToString()); 

    FormattedDisplayTextBox.Clear(); 
    FormattedDisplayTextBox.Text = sb.ToString(); 
} 

private List<string> GetTextAsStringList() 
{ 
    List<string> stringList = new List<string>(); 
    int pos = 0; 
    string inputText = InputTextBox.Text; 

    CustomTextSource store = new CustomTextSource(); 
    store.Text = inputText; 
    store.FontRendering = new FontRendering(InputTextBox.FontSize, 
              InputTextBox.TextAlignment, 
              null, 
              InputTextBox.Foreground, 
              new Typeface(InputTextBox.FontFamily, 
               InputTextBox.FontStyle, 
               InputTextBox.FontWeight, 
               InputTextBox.FontStretch)); 

    using (TextFormatter formatter = TextFormatter.Create()) 
    { 
     while (pos < store.Text.Length) 
     { 
      using (TextLine line = formatter.FormatLine(store, 
            pos, 
            InputTextBox.ViewportWidth, 
            new GenericTextParagraphProperties(
             store.FontRendering), 
            null)) 
      { 
       stringList.Add(inputText.Substring(pos, line.Length - 1)); 
       pos += line.Length; 
      } 
     } 
    } 

    return stringList; 
} 
+0

哇,谢谢很多作品perferct :)。由于除了最后一行以外,每行的最后一个字符都被截断,所以我不得不调整一下代码。 – Fbeauche 2011-04-21 16:12:46

+1

您可以使用所做的修复来编辑答案吗? – 2012-07-30 18:13:57

+0

指向“高级文本格式示例”的链接已中断。 – Victor 2016-11-19 12:44:56

1

为此,您必须使用文本测量API编写自己的逻辑。

STEP 1: Bresk将文本框中的文本输入到单词中。

第2步:然后测量每个字宽并合并它们,直到线宽小于文本框宽度。

请参阅这篇文章,它解释了关于文本测量过程。 (social.msdn.microsoft.com/forums/en-US/wpf/thread/...)

+0

这不是重点,他/她希望以TextBlock自动对文本施加的格式获取文本。 – 2011-04-19 17:55:41

+0

@ H.B。我的坏!我以为他正在寻找方式来处理溢出文本,而不使用TextBox。 – 2011-04-19 18:03:28

+0

@ H.B。顺便说一句,在这种情况下,将文本框只读是否是一个有效的选项? – 2011-04-19 18:04:39

1

伊恩·格里菲思回答这个问题:Get Displayed Text from TextBlock

它得到显示的文本(因为它是在TextBlock,但我认为你应该能够使用它的TextBox以及

+0

好帖子那里,但我似乎并没有得到它与文本框很好地工作。我能够通过一些调整获得显示的文本,但我无法获得文本框中的整个文本... – Fbeauche 2011-04-20 14:09:43

1

如果你想要的只是文本框的文本(完整的文本,而不只是可见的部分),是在某些文本块的同一窗口中显示为文本(带明显换行符),快速入门可能是:

FormattedText ft = new FormattedText(textBox1.Text, 
    System.Globalization.CultureInfo.CurrentCulture, 
    textBox1.FlowDirection, 
    new Typeface(textBox1.FontFamily, 
     textBox1.FontStyle, 
     textBox1.FontWeight, 
     textBox1.FontStretch), 
    textBox1.FontSize, 
    textBox1.Foreground); 
ft.TextAlignment = textBox1.TextAlignment; 
ft.Trimming = TextTrimming.None; 

ft.MaxTextWidth = textBox1.ViewportWidth; 

textBlock1.Width = textBox1.ViewportWidth; 
textBlock1.Height = ft.Height; 

textBlock1.TextAlignment = textBox1.TextAlignment; 
textBlock1.TextWrapping = textBox1.TextWrapping; 
textBlock1.Text = textBox1.Text; 

如果在其他地方需要它,可以将值带到那个地方并在那里使用它们的文本块。

如果需要将整个文本(带明显换行符)作为字符串列表(例如List<string>),其中每个项目表示明显行,则需要一个复杂的解决方案。
此外,如果您只需要文本框中显示的文本的可见部分,则还需要一些复杂的解决方案。

+0

我需要完整的文本,即时消息不使用它来显示在屏幕上:( – Fbeauche 2011-04-20 14:07:31