【问题标题】:WPF: Get "wrapped" text out of a textboxWPF:从文本框中获取“包装”文本
【发布时间】:2011-08-08 21:12:28
【问题描述】:

当 TextWrapping="Wrap" 时,WPF 中是否有一种方法可以将文本格式化为文本框上显示的格式?

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

我尝试使用 TextFormatter 类,但它只允许我将文本绘制到绘图上下文中,我只需要包含换行符的文本。

【问题讨论】:

  • 很抱歉,但无法理解问题陈述。您是否要从该文本框中复制文本并在粘贴到其他位置时想要保留包装位置?
  • 作为文本还是作为视觉/图像?
  • @publicgk,我的确切情况是将文本传递给活动报告,同时保留包装位置,因此我得到的包装与屏幕上显示的相同。所以我需要它作为文本。

标签: c# .net wpf


【解决方案1】:

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

第 1 步: 将文本框文本插入单词。

步骤 2: 然后测量每个单词的宽度并将它们组合起来,直到行宽小于文本框宽度。

请参阅这篇解释文本测量过程的帖子。 (social.msdn.microsoft.com/forums/en-US/wpf/thread/...)

【讨论】:

  • 这不是重点,他/她想要获取 TextBlock 自动强加在文本上的格式的文本。
  • @H.B.我的错!..我以为他正在寻找不使用 TextBox 来处理溢出文本的方法。
  • @H.B.顺便说一句,在这种情况下,将文本框设为只读会是一个有效的选项吗?
  • 不,我需要用户输入文本
  • 谢谢,我刚刚修改了我的答案。有时稍后会发布 code-sn-p。
【解决方案2】:

查看Ian Griffiths对此问题的回答:Get Displayed Text from TextBlock

它从TextBlock 获取显示的文本(在屏幕上显示),但我认为您应该也可以将它用于TextBox

【讨论】:

  • 那里的帖子不错,但我似乎无法很好地使用文本框。我可以通过一些调整来获得显示的文本,但我无法在文本框中获取整个文本......
【解决方案3】:

如果您想要的只是文本框的文本(完整的文本,而不仅仅是可见部分),在某个文本块的同一窗口中显示为文本(带有明显的换行符),快速破解强> 可能是:

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&lt;string&gt;),其中每个项目代表明显的行,您将需要一个复杂的解决方案。
另外,如果您只需要文本框中显示的文本的可见部分,则需要一些复杂的解决方案。

【讨论】:

  • 我需要完整的文本,我没有使用它在屏幕上显示它:(
【解决方案4】:

以下是获取带有明显换行符的完整文本的方法。

注意:

  • 在您的项目中包含来自Advanced Text Formatting Example 的以下类:
    • 自定义文本源
    • 字体渲染
    • GenericTextProperties
  • CustomTextSource 类中提到了一些限制。不过,我相信您的要求不会受到这些限制的影响。
  • 这些只是示例。您可能需要根据需要修改代码。
  • 代码仍然使用 hack(虽然不错) - 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;
}

【讨论】:

  • 哇,非常感谢,完美的工作:)。我不得不稍微调整一下代码,因为它会截断除最后一个之外的每一行的最后一个字符。
  • “高级文本格式设置示例”的链接已损坏。
猜你喜欢
  • 2011-12-11
  • 1970-01-01
  • 1970-01-01
  • 2021-08-31
  • 1970-01-01
  • 2016-10-29
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多