Как создать редактор элементов управления WYSIWYG TextBox для вертикально центрированных сообщений, отправляемых на мобильное устройство? - PullRequest
1 голос
/ 08 апреля 2011

У меня есть WPF TextBox, который содержит семь строк текста и имеет возможность переноса слов.

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

Как вы можете видеть в XAML выше, текст центрируется по вертикали и горизонтали. Когда я набираю короткую фразу, которая помещается на одной строке, текст появляется на 4-й строке элемента управления, как и ожидалось, поскольку VerticalContentAlignment имеет значение «Center».

Текст, введенный пользователем, предназначен для отправки на мобильное устройство с дисплеем, который содержит семь строк текста и использует «\ n» для переноса на следующую строку. Предполагается, что отображение текста на мобильном устройстве выглядит так же, как то, что вводится в элемент управления TextBox. По крайней мере, по количеству строк текста, центрированию и разрывам строк.

Таким образом, когда пользователь заканчивает ввод текста в элемент управления TextBox и нажимает кнопку «Отправить сообщение», необходимо выполнить некоторую постобработку введенного текста перед его отправкой на мобильное устройство.

Текст, введенный в элемент управления TextBox, должен иметь символы новой строки (\ n), добавляемые везде, где текст переносится на новую строку в элементе управления TextBox. Например, в тех случаях, когда элемент управления отображает несколько строк текста, я копирую текст TextBox и добавляю новую строку между строками, когда элемент управления TextBox переносит строки текста, введенные пользователем.

Поэтому, когда пользователь нажимает кнопку «Отправить сообщение», это код, который выполняет постобработку:

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

Учитывая приведенный выше код, я ожидаю, что выходные данные для одной строки текста будут выглядеть примерно так: "\ n \ n \ n \ nFoo". Тем не менее, вывод «\ nFoo \ nFoo \ nFoo \ nFoo». Устанавливая точку останова в коде, я вижу, что textBox.GetLineText (index) для индексов с 0 по 3 возвращает «Foo» для каждого индекса, даже если «Foo» отображается только один раз в элементе управления TextBox.

Так что, думаю, у меня действительно есть два вопроса:

1) Почему GetLineText возвращает LineCount со значением 4 для каждой строки, имеющей один и тот же текст, когда пользователь ввел только одну строку текста (которая помещается на одной строке в элементе управления TextBox)?

2) Какой простой способ обойти эту проблему, сохранить введенный текст по центру в элементе управления TextBox и отправить на удаленное устройство текстовое сообщение, которое будет отображаться пользователем, видимым в элементе управления TextBox?

Примечания: Я не могу просто удалить повторяющиеся строки текста и заменить их на «\ n», так как пользователь мог набрать один и тот же текст на нескольких строках. Кроме того, я мог бы просто выровнять введенный текст по вертикали, а не по центру. Я проверил это работает, но не дает истинного опыта WYSIWIG.

Ответы [ 2 ]

1 голос
/ 08 апреля 2011

Похоже, ошибка в методе.Вы можете обойти это, обернув текстовое поле другим элементом управления, который выполняет вертикальное центрирование, или выделив строки через свойство text.

    <StackPanel Orientation="Vertical" VerticalAlignment="Center">
    <TextBox AcceptsReturn="True" HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" BorderThickness="0"> </TextBox>
    </StackPanel>
0 голосов
/ 09 апреля 2011

Следующий модифицированный код из показанного выше метода решает проблему. Однако мне все еще любопытно, если у 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;
  }
...