How to create a WYSIWYG TextBox management editor for vertically centered messages sent to a mobile device?

I have a WPF text block that contains seven lines of text and has word wrap.

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

As you can see in the XAML above, the text is centered vertically and horizontally. When I print a short phrase that fits on one line, the text appears on the 4th line of the control, as expected, since VerticalContentAlignment is the "Center".

The text entered by the user is intended to be sent to a mobile device with a display that contains seven lines of text and uses "\ n" to transfer to the next line. The goal is that displaying text on a mobile device looks the same as displaying text in a TextBox control. At least how many lines of text, centering and line breaks.

Therefore, when the user finishes entering text into the TextBox control and clicks the "Send Message" button, some post-processing should be performed on the entered text before sending to the mobile device.

The text entered in the TextBox control must contain newline characters (\ n), where the text is wrapped to a new line in the TextBox control. For example, in cases where the control shows several lines of text, I copy the TextBox text and add a new line between the lines in which the TextBox control wrapped the lines of text entered by the user.

So, when the user clicks the "Send Message" button, this is the code that performs the mail 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 above code, I expect the output for one line of text to look something like this: "\ n \ n \ n \ nFoo". However, the output is "\ nFoo \ nFoo \ nFoo \ nFoo". By setting a breakpoint in the code, I see that textBox.GetLineText (index) for indices 0 through 3 returns "Foo" for each index, although "Foo" is displayed only once in the TextBox control.

So, I really have two questions:

1) Why does GetLineText return a LineCount of 4 with each line having the same text when the user entered only one line of text (which fits on one line in a TextBox control)?

2) What is an easy way to get around this, save the entered text in the TextBox control center and send a text message to the remote device that will be displayed, as the user can see in the TextBox control?

Notes: I cannot just delete duplicate lines of text and replace them with "\ n", because the user could type the same text on multiple lines. Also, I could just align the entered text with a vertical top instead of a vertical center. I tested this, but does not give a true WYSIWIG experience.

+1
source share
2 answers

Looks like an error in the method. You can get around this by either wrapping the text field with another control that performs vertical centering, or by extracting the lines through the text property.

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

The following modified code from the method shown above solves the problem. However, I'm still wondering if Microsoft has an error with the textBox.GetLineText method.

  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; } 
0
source

Source: https://habr.com/ru/post/1275540/


All Articles