简体   繁体   English

如何为发送到移动设备的垂直居中消息创建WYSIWYG TextBox控件编辑器?

[英]How do you create a WYSIWYG TextBox control editor for vertically centered messages sent to a mobile device?

I have a WPF TextBox that holds seven lines of text and has word wrapping enbabled. 我有一个WPF文本框,可容纳七行文本,并具有自动换行功能。

<TextBox TextWrapping="Wrap" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" MaxLines="7"/>

As you can see in the XAML above the text is centered vertically and horizontally. 如您在XAML上方所见,文本在垂直和水平方向上居中。 When I type a short phrase that fits on a single line, the text appears on the 4th line of the control as expected since the VerticalContentAlignment is "Center". 当我键入适合单行的简短短语时,由于VerticalContentAlignment为“ Center”,因此文本按预期出现在控件的第四行。

The text that is entered by the user is meant to be sent to a mobile device that has a display that holds seven lines of text and uses the "\\n" to wrap to the next line. 用户输入的文本应发送到具有显示屏的移动设备,该显示屏包含七行文本,并使用“ \\ n”换行到下一行。 The intent is that the display of text on the mobile device looks the same as what is entered into the TextBox control. 目的是使文本在移动设备上的显示与在TextBox控件中输入的内容相同。 At least as far as number of lines of text, centering, and where line breaks occur. 至少与文本的行数,居中以及出现换行符的位置有关。

So when the the user finishes entering the text into the TextBox control and clicks the "Send Message" button, some post-processing must be done on the entered text before sending it to the mobile device. 因此,当用户完成将文本输入到TextBox控件中并单击“发送消息”按钮时,必须先对输入的文本进行一些后处理,然后才能将其发送到移动设备。

The text entered into TextBox control needs to have newline (\\n) characters added wherever the text wraps to a new line in the TextBox control. 输入到TextBox控件中的文本需要在文本换行到TextBox控件中的新行的任何位置添加换行符(\\ n)。 For example, in cases where the control is showing multiple lines of text, I copy the TextBox's text and add a newline between the lines wehre the TextBox control wrapped the lines of text that were entered by the user. 例如,在控件显示多行文本的情况下,我复制了TextBox的文本,并在两行之间添加了换行符,因为TextBox控件包装了用户输入的文本行。

So when the user clicks a "Send Message" button this is the code that does the post processing: 因此,当用户单击“发送消息”按钮时,这是进行后期处理的代码:

  public static String AddNewLineCharsToMessage(TextBox textBox)
  {
     String message = String.Empty;

     if (textBox == null) return message;

     // First strip all the carriage returns and newline characters
     // so we don't have duplicate newline characters in the message.
     // Then add back in just the newline characters which is what the 
     // mobile device uses to wrap lines.

     // Just assign the text if we have a single line message
     if (textBox.LineCount < 2)
        return textBox.Text;

     var textLines = new List<string>(5);
     int lineCount = Math.Min(textBox.LineCount, textBox.MaxLines);
     for (Int32 index = 0; index < lineCount; index++)
     {
        if (textBox.GetLineText(index).Length > 0)
        {
           textLines.Add(textBox.GetLineText(index));
           textLines[index] = textLines[index].Replace("\r", "");
           textLines[index] = textLines[index].Replace("\n", "");
        }
        else
           textLines.Add("\n");
     }

     message = String.Empty;
     for (Int32 index = 0; index < lineCount; index++)
        message += textLines[index] + (index < lineCount - 1 ? "\n" : "");

     return message;
  }

Given the code above, I would expect the output for a single line of text to look something like: "\\n\\n\\n\\nFoo". 给定上面的代码,我希望一行文本的输出看起来像:“ \\ n \\ n \\ n \\ nFoo”。 However, the output is "\\nFoo\\nFoo\\nFoo\\nFoo". 但是,输出为“ \\ nFoo \\ nFoo \\ nFoo \\ nFoo”。 Setting a break point in the code I see that textBox.GetLineText(index) for indices 0 through 3 returns "Foo" for each index even though "Foo" is only shown once in the TextBox control. 在代码中设置一个断点,我看到索引0到3的textBox.GetLineText(index)为每个索引返回“ Foo”,即使“ Foo”在TextBox控件中仅显示一次。

So I guess I really have two questions: 所以我想我真的有两个问题:

1) Why does GetLineText return a LineCount of 4 with every line having the same text, when only a single line of text (that fits on one line in the TextBox control) was entered by the user? 1)当用户仅输入一行文本(适合于TextBox控件中的一行)时,为什么GetLineText返回LineCount为4的每一行具有相同的文本?

2) What is an easy way to work around this, keep the entered text centered in the TextBox control, and send the remote device the text message that will be displayed as seen by the user on the TextBox control? 2)有一种简单的方法可以解决此问题,将输入的文本保持在TextBox控件的中心,然后向远程设备发送将显示的文本消息,如用户在TextBox控件上看到的那样?

Notes: I cannot simply remove duplicate lines of text and replace them with "\\n" as the user may have typed in the same text on multiple lines. 注意:我不能简单地删除重复的文本行并将其替换为“ \\ n”,因为用户可能在多行中输入了相同的文本。 Also, I could simply align the entered text to the vertical top instead of the vertical center. 另外,我可以简单地将输入的文本对齐到垂直顶部而不是垂直中心。 I have verified this works, but does not give a true WYSIWIG experience. 我已经验证了此功能,但是并没有提供真正的所见即所得的体验。

Looks like a bug in the method. 看起来像方法中的错误。 You could work around this by either wrapping the textbox with another control that does the vertical centering or by extracting the lines via the text property. 您可以通过以下方式解决此问题:将文本框与另一个进行垂直居中的控件包装在一起,或者通过text属性提取线条。

    <StackPanel Orientation="Vertical" VerticalAlignment="Center">
    <TextBox AcceptsReturn="True" HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" BorderThickness="0"> </TextBox>
    </StackPanel>

The following modified code from the method shown above solves the problem. 通过上面显示的方法,下面的修改后的代码解决了该问题。 I am still curious however if Microsoft has a bug with the textBox.GetLineText method. 但是我仍然很好奇,如果Microsoft在textBox.GetLineText方法中存在错误。

      public static String AddNewLineCharsToMessage(TextBox textBox)
  {
     String message = String.Empty;

     if (textBox == null) return message;

     // Just assign the text if we have a single line message
     if (textBox.LineCount < 2)
        return textBox.Text;


     // Find the index for the first line that contains text displayed in the TextBox.
     // GetLineText(index) will return the text displayed/entered by the user for indices less
     // than the index of the line that the text is actually displayed on.  This seems to be
     // a bug to me, but I will workaround this Microsoft weirdness.

     // Find the index of first line that actually displays text by using the length of TextBox.Text
     Int32 firstTextLineIndex = 0;
     Int32 textLen = textBox.Text.Length;
     Int32 textLinesLen = 0;

     for (Int32 firstTextLine = textBox.LineCount - 1; firstTextLine >= 0; firstTextLine--)
     {
        textLinesLen += textBox.GetLineText(firstTextLine).Length;
        if (textLinesLen >= textLen)
        {
           firstTextLineIndex = firstTextLine;
           break;
        }
     }

     // First strip all the carriage returns and newline characters
     // so we don't have duplicate newline characters in the message.
     // Then add back in just the newline characters which is what the car
     // code uses to parse out the message to be displayed on each line.

     var textLines = new List<string>(5);
     int lineCount = Math.Min(textBox.LineCount, textBox.MaxLines);
     for (Int32 index = 0; index < lineCount; index++)
     {
        if (index < firstTextLineIndex)
           textLines.Add("");
        else  // if (textBox.GetLineText(index).Length > 0)
        {
           textLines.Add(textBox.GetLineText(index));
           textLines[index] = textLines[index].Replace("\r", "");
           textLines[index] = textLines[index].Replace("\n", "");
        }
     }

     message = String.Empty;
     for (Int32 index = 0; index < lineCount; index++)
        message += textLines[index] + (index < lineCount - 1 ? "\n" : "");

     return message;
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM