Предотвращение горизонтального расширения TextBox в WPF - PullRequest
8 голосов
/ 28 июля 2011

У меня в App.xaml определен следующий стиль

<Style x:Key="textBoxMultiline" TargetType="{x:Type TextBox}" >
    <Setter Property="VerticalScrollBarVisibility" Value="Auto" />
    <Setter Property="HorizontalScrollBarVisibility" Value="Hidden" />
    <Setter Property="MinHeight" Value="50" />
    <Setter Property="TextWrapping" Value="Wrap" />
</Style>

И во всем решении мы используем его в каждом текстовом поле, для которого требуется краткий текст.

<TextBox x:Name="textBoxDescription" Grid.Row="2" Grid.Column="1" Style="{DynamicResource textBoxMultiline}" />

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

<ScrollViewer Height="Auto" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
   ...
</ScrollViewer>

Странно, но TextBox с указанным выше стилем начинают расширяться вправо вместо переноса текста.

Есть ли способ предотвратить это, не удаляя ScrollViewer?

Ответы [ 5 ]

7 голосов
/ 28 июля 2011

Если вы не хотите жестко кодировать ширину, тогда вы можете перейти к привязке элемента к ширине родительского элемента ... вот пример

Здесь я привязываю текстовое поле maxwidth с фактической шириной scrolviewer .. а также вы должны убедиться, что ширина столбца определения установлена ​​на «*», а не на «Авто». если вы установите его на Auto, он будет пренебрегать шириной ScrollViewer и продолжит увеличивать ширину ScrollViewer и текстового поля. я думаю, что в этом случае вы упадете ....

<Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"></ColumnDefinition>
            <ColumnDefinition Width="*"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <ScrollViewer HorizontalScrollBarVisibility="Auto" Name="scv">
            <TextBox Height="30" TextWrapping="Wrap" MaxWidth="{Binding ElementName=scv,Path=ActualWidth}"></TextBox>
        </ScrollViewer>
    </Grid>
7 голосов
/ 28 июля 2011

Вы должны определить MaxWidth для TextBox, в противном случае ограничений нет, поскольку ScrollViewer.

5 голосов
/ 15 мая 2012

Решение, предоставленное @bathineni, помогло мне решить мою проблему. Вот что сработало для меня:

    <Grid >
      <Grid.ColumnDefinitions>
      <ColumnDefinition Width="50"/>
      <ColumnDefinition  Width="*"/>
    </Grid.ColumnDefinitions>
      <Button Grid.Column="0" Width="30" Height="23" Margin="10,5" Content="..."/>
      <ScrollViewer  Grid.Column="1" HorizontalScrollBarVisibility="Disabled" verticalScrollBarVisibility="Disabled" Name="scv">
           <TextBox Height="25" Text="Insert here long text" MaxWidth="{Binding ElementName=scv, Path=ActualWidth}" HorizontalAlignment="Stretch" />
      </ScrollViewer>
    </Grid>
0 голосов
/ 24 августа 2018

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

Итак, я нашел следующее решение, используя 2 текстовых поля, чтобы работать для меня.Первое текстовое поле - это текстовое поле, отображаемое для ввода пользователем своего ввода, а 2-е текстовое поле инициализируется через свойство зависимости (DisplayLength) и преобразователь, показанный ниже.

Привязка свойства MaxWidth 1-го TextBox к свойству Width 2-го TextBox фиксирует размер так, что пользователи могут вводить то, что им нужно, но отображаемая ширина текстового поля не изменится, даже если будет больше места для интерфейсадоступно ...

<TextBox x:Name="PART_TextBox"
    Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Value}"
    Margin="0,0,1,0"
    TextAlignment="Right"
    AcceptsReturn="False"
    SpellCheck.IsEnabled="False"
    HorizontalContentAlignment="Stretch"
    VerticalContentAlignment="Center"
    HorizontalAlignment="Stretch"
    VerticalAlignment="Stretch"
    MaxWidth="{Binding ElementName=TBMeasure, Path=ActualWidth}"
    />

<!-- Hidden measuring textbox ensures reservation of enough UI space
     according to DisplayLength dependency property
-->
<TextBox x:Name="TBMeasure"
    Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DisplayLength, Converter={StaticResource ByteToPlaceHolderStringConverter}}"
    Margin="0,0,1,0"    
    TextAlignment="Right"
    AcceptsReturn="False"
    SpellCheck.IsEnabled="False"
    HorizontalContentAlignment="Right"
    VerticalContentAlignment="Center"
    HorizontalAlignment="Stretch"
    VerticalAlignment="Stretch"
    Visibility="Hidden"/>



// Converter
[ValueConversion(typeof(byte), typeof(string))]
public sealed class ByteToPlaceHolderStringConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if ((value is byte) == false)
            return Binding.DoNothing;

        byte byteVal = (byte)value;

        string retString = string.Empty;
        for (int i = 0; i < byteVal; i++)
            retString = retString + "X";

        return retString;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return Binding.DoNothing;
    }
}
0 голосов
/ 10 июля 2013

У меня работает.Если вы хотите, чтобы полосы прокрутки появлялись в текстовом поле, вы можете добавить

HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"

в TextBox

...