TextBox

68

Как правило, элемент TextBox хранит одну строку текста. (Допустимое количество символов можно ограничить с помощью свойства MaxLength.) Однако часто бывает нужно многострочное текстовое окно для работы с большим объемом содержимого. Для этой цели нужно присвоить свойству TextWrapping значение Wrap или WrapWithOverflow. При значении Wrap текст всегда разрывается на краю элемента управления, даже если придется разбить слишком длинные слова. WrapWithOverflow позволяет некоторым строкам выйти за правый край, если не найдется подходящее место (например, пробел или дефис) для разбиения строки.

Чтобы текстовое поле действительно содержало несколько строк, оно должно иметь достаточные размеры. Вместо указания жестко закодированной высоты (которая не подойдет для разных размеров шрифтов и может вызвать проблемы с компоновкой) лучше использовать свойства MinLines и MaxLines. Свойство MinLines определяет минимальное количество строк, которые должны отображаться в текстовом поле. Например, если этому свойству присвоить значение 2, то высота текстового поля будет равна высоте минимум двух строк текста. Свойство MaxLines задает максимальное количество отображаемых строк. Даже если текстовое окно будет развернуто до размеров контейнера (например, строка Grid с пропорциональным размером или последний элемент в DockPanel), оно не превысит заданный лимит.

Свойства MinLines и MaxLines не влияют на объем содержимого, которое можно поместить в текстовом поле. Они просто придают нужный размер текстовому окну. В коде можно проверить свойство LineCount, чтобы узнать точно, сколько строк умещается в текстовом окне.

Если текстовое поле поддерживает переносы строк, то пользователь может ввести и больше текста, чем может быть отображено в видимых строках. По этой причине обычно имеет смысл добавить постоянно видимую (или отображаемую по запросу) полосу прокрутки, присвоив свойству VerticalScrollBarVisibiliity значение Visible или Auto. (Можно задать и свойство HorizontalScrollBarVisibility, чтобы отображать реже используемую горизонтальную полосу прокрутки.)

Иногда нужно, чтобы пользователь мог вводить разрывы строк в многострочном текстовом поле, нажимая клавишу <Enter>. (Обычно при нажатии клавиши <Enter> в текстовом поле срабатывает кнопка по умолчанию.) Чтобы текстовое поле поддерживало клавишу <Enter>, присвойте свойству AcceptsReturn значение true. Можно также задать свойство AcceptsTab, чтобы пользователь мог вставлять символы табуляции. Иначе при нажатии клавиши <Tab> фокус будет передаваться следующему элементу управления в последовательности переходов с помощью клавиши табуляции.

Иногда текстовые поля создаются исключительно для отображения текста. В этом случае задайте свойство IsReadonly равным true, чтобы запретить редактирование текста. Это лучше блокирования текстового поля путем присваивания свойству IsEnabled значения false, т.к. заблокированное текстовое окно выводит серый текст (его труднее читать), не поддерживает выделение текста (или копирование в буфер обмена) и его прокрутку.

Выделение текста

Как известно, в любом текстовом поле можно выделить текст — щелкнув кнопкой мыши и переместив ее указатель или с помощью клавиш управления курсором при прижатой клавише <Shift>. Класс TextBox дает возможность определить или изменить выделенный в данный момент текст программным образом, используя свойства SelectionStart, SelectionLength и SelectedText.

Свойство SelectionStart определяет позицию, с которой начинается выделение текста (нумерация с нуля). Например, если этому свойству присвоить значение 10, то первым выделенным символом будет одиннадцатый символ в текстовом поле. Свойство SelectionLength указывает общее количество выделенных символов. (Нулевое значение говорит о том, что не было выделено ни одного символа.) И, наконец, свойство SelectedText позволяет быстро проверить или изменить выделенный текст в текстовом поле. Реагировать на изменение выделения можно с помощью обработки события SelectionChanged. Ниже показан пример, который реагирует на это событие и выводит информацию о текущем выделении текста:

<Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"></RowDefinition>
            <RowDefinition Height="auto"></RowDefinition>
            <RowDefinition Height="auto"></RowDefinition>
        </Grid.RowDefinitions>
        <TextBox TextWrapping="Wrap" Padding="5" AutoWordSelection="True" Name="txt"
                 SelectionChanged="TextBox_SelectionChanged">
            Формально сущность, используемая для хранения набора вычисляемых значений, 
            называется виртуальным стеком выполнения ...
        </TextBox>
        <Label Grid.Row="1" Margin="5">Выделенный текст: </Label>
        <TextBlock TextWrapping="Wrap" Grid.Row="2" Margin="5" x:Name="txb_Selected"></TextBlock>
</Grid>
private void TextBox_SelectionChanged(object sender, RoutedEventArgs e)
{
     if (txb_Selected == null) return;
     txb_Selected.Text = String.Format("Выделено начиная с {0} - {1} символов: \"{2}\"",
          txt.SelectionStart,txt.SelectionLength,txt.SelectedText);
}
Работа с TextBlock

В классе TextBox имеется также свойство AutoWordSelection, позволяющее управлять поведением выделения. Если оно равно true, то выделение в текстовом окне будет производиться по словам.

Еще одной полезной функцией элементов TextBox является возможность отмены последних изменений. Такую отмену можно выполнить программно (используя метод Undo()) и с помощью сочетания клавиш <Ctrl+Z> — если свойство CanUndo не равно false.

При программной обработке текста в текстовом поле можно использовать методы BeginChange() и EndChange() для оформления последовательности действий, которую элемент TextBox будет считать единым блоком изменений. Эти действия можно затем отменить одним шагом.

Пройди тесты
Лучший чат для C# программистов