Разрешить изменять размер текстового поля, но не увеличивать его при вводе пользователем
Вопрос
У меня есть текстовое поле, определенное внутри окна следующим образом:
<Window x:Class="NS.MainWindow"
...
SizeToContent="WidthAndHeight">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition MinWidth="200" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition MinHeight="50" />
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0">Description:</TextBlock>
<TextBox Grid.Column="1" Grid.Row="0" TextWrapping="WrapWithOverflow" />
</Grid>
</Window>
Проблема в том, что когда пользователь вводит текстовое поле, оно расширяется вправо, поскольку задана только минимальная ширина.Чего я действительно хочу, так это перенести текст на следующую строку.Я могу заставить его сделать это, если вместо этого изменю минимальную ширину столбца на ширину.Однако, если я сделаю это, то текстовое поле больше не будет изменять размер при изменении размера окна.
Есть ли способ, которым я могу получить и то, и другое?(т.е.изменять размер только при изменении размера окна, в противном случае переносить)
Решение
Причина, по которой у вас такое поведение, заключается в том, что вы установили Свойство SizeToContent окна - который в основном разрешает окну изменять размер самого себя в зависимости от размера, запрошенного его содержимым.Итак, по мере того, как вы вводите больше информации, текстовое поле сообщает, что мне нужно больше места, и окно послушно увеличивается.Ваше текстовое поле не будет увеличиваться, если вы не установите свойство SizeToContent.
Поэтому я бы сказал, потеряйте установщик свойств SizeToContent и используйте пропорциональный размер сетки.Здесь я говорю, чтобы столбец № 2 был в два раза шире столбца № 1.Значение "Растягивания" по умолчанию для HorizontalAlignment и VerticalAlignment для сетки должно гарантировать, что ваши элементы управления будут корректно изменять размер при изменении размера окна.
<Window ...
Title="MyWindow" WindowStyle="ToolWindow" ResizeMode="CanResizeWithGrip"
MinWidth="300" Width="300" Height="80">
<Grid x:Name="myGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" MinWidth="100"/>
<ColumnDefinition Width="2*" MinWidth="200" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition MinHeight="50" />
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0">Description:</TextBlock>
<TextBox Grid.Column="1" Grid.Row="0" TextWrapping="WrapWithOverflow"/>
</Grid>
Если вы просто добавите параметр настройки свойства SizeToContent обратно в приведенный выше фрагмент кода...вы бы увидели какое-то странное поведение, когда текстовое поле изначально увеличивается вместе с текстовым содержимым..однако, если вы измените размер окна один раз..текстовое поле перестанет расти.Странно...не могу объяснить такое поведение.
HTH
Другие советы
Похоже, что в текстовом поле WPF нет такой встроенной опции.
Чтобы решить эту проблему, вы можете использовать пользовательское текстовое поле, которое сообщает желаемый размер (0, 0).Это уродливый взлом, но он работает.
В вашем файле MainWindow.xaml.cs:
namespace NS
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
...
}
// Ugly HACK because the regular TextBox doesn't allow autoresize to fit the parent but NOT autoresize when the text doesn't fit.
public class TextBoxThatDoesntResizeWithText : TextBox
{
protected override Size MeasureOverride(Size constraint)
{
return new Size(0, 0);
}
}
}
Затем в вашем файле MainWindow.xaml:
<Window x:Class="NS.MainWindow"
...
xmlns:local="clr-namespace:NS"
SizeToContent="WidthAndHeight">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition MinWidth="200" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition MinHeight="50" />
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0">Description:</TextBlock>
<local:TextBoxThatDoesntResizeWithText Grid.Column="1" Grid.Row="0" TextWrapping="WrapWithOverflow" />
</Grid>
</Window>
Измените определение второго столбца на Width="*".