Поведение WPF TextBox и Scroll - PullRequest
       32

Поведение WPF TextBox и Scroll

11 голосов
/ 22 декабря 2008

У меня проблема. Мне нужно разместить сетку с элементами управления в ScrollViewer, чтобы текстовое поле не было усечено или свернуто до нуля с помощью пользовательского интерфейса. Также я хочу, чтобы текстовое поле расширялось, когда пользователь изменял ширину окна. Я устанавливаю содержимое окна следующим кодом

<DockPanel>
    <TreeView DockPanel.Dock="Left" Width="150"/>
    <ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <TextBlock Text="Name" 
                       Margin="5" 
                       VerticalAlignment="Center"/>
            <TextBox Grid.Column="1"
                     Text="Some Name"
                     Margin="5"
                     VerticalAlignment="Center"
                     MinWidth="200"/>
        </Grid>
    </ScrollViewer>
</DockPanel>

Все работает нормально, но когда пользователь вводит очень длинный текст в TextBox, он расширяется и появляется горизонтальная прокрутка. Есть ли простой способ ограничить максимальную ширину TextBox и разрешить ее расширение только при изменении размера окна пользователем.

Ответы [ 3 ]

33 голосов
/ 22 декабря 2008

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

Одним из решений здесь является создание другого элемента с автоматическим размером и привязка к нему TextBox.Width:

<DockPanel>
    <TreeView Width="150" DockPanel.Dock="Left"/>
    <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <TextBlock Margin="5" VerticalAlignment="Center" Text="Name"/>
            <Border x:Name="b" Grid.Column="1" Margin="5"/>
            <TextBox Width="{Binding ActualWidth, ElementName=b}"
                     MinWidth="200"
                     Grid.Column="1"
                     Margin="5"
                     VerticalAlignment="Center"
                     Text="Some Name"/>
        </Grid>
    </ScrollViewer>
</DockPanel>

Обратите внимание, что мы устанавливаем свойство Margin элемента авторазмера (Border). Это важно, поскольку, если он не установлен, будет цикл:

  1. Ширина границы автоматически изменяется до ширины столбца сетки
  2. Ширина TextBox изменяется до Border.ActualWidth
  3. Ширина столбца сетки изменяется до ширины TextBox + поле TextBox
  4. Ширина границы снова автоматически изменяется до ширины столбца сетки

Если задать для поля Margin то же значение, что и для TextBox, изменение размера TextBox не повлияет на размер сетки.

2 голосов
/ 26 ноября 2011

Переопределение TextBox.MeasureOverride как у меня так сработало:

protected override Size MeasureOverride(Size constraint)
{
    Size origSize = base.MeasureOverride(constraint);
    origSize.Width = MinWidth;
    return origSize;
}
0 голосов
/ 01 января 2011

нет - это хорошо известная проблема wpf, которая должна быть исправлена ​​в следующем выпуске. спасибо

...