阻止 ScrollViewer 中的 TextBox 随着内容增长
Stop TextBox in ScrollViewer from growing with content
我有一个 HorizontalScrollBarVisibility 设置为 "Auto" 的 ScrollViewer,其中包含一个 TextBox。问题在于,当用户输入文本时,TextBox 会不断增长以显示全部内容。我需要更改什么,以便 TextBox 仅获取可用宽度(但不小于给定的最小宽度)?
仅当可用水平滚动条 space 不足以满足给定的最小宽度时,才应显示水平滚动条。
只有当有更多水平 space 可用时,TextBox 才应该增长。
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*" MinWidth="50"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Text="test:"/>
<TextBox Grid.Column="1"/>
</Grid>
</ScrollViewer>
即使满足 MinWidth 约束,水平滚动条也会出现:
这似乎是一个普遍的问题,但我还没有在网上找到满意的解决方案。
这是我的解决方案:
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*" MinWidth="100"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Text="test:"/>
<local:TextBoxDecorator Grid.Column="1">
<TextBox Text="content content content content content content"/>
</local:TextBoxDecorator>
</Grid>
</ScrollViewer>
c#
public class TextBoxDecorator : Decorator {
// properties
public override UIElement Child {
get {
return base.Child;
}
set {
var oldValue = base.Child;
if (oldValue != null) {
var binding = BindingOperations.GetBinding(oldValue, FrameworkElement.WidthProperty);
if ((binding != null) && (binding.Source == this))
BindingOperations.ClearBinding(oldValue, FrameworkElement.WidthProperty);
}
base.Child = value;
if ((value != null) &&
BindingOperations.GetBinding(value, FrameworkElement.WidthProperty) == null)
BindingOperations.SetBinding(
value,
FrameworkElement.WidthProperty,
new Binding() {
Source = this,
Path = new PropertyPath(FrameworkElement.ActualWidthProperty),
Mode = BindingMode.OneWay
});
}
}
// methods
protected override Size MeasureOverride(Size constraint) {
Size result = base.MeasureOverride(constraint);
if (double.IsInfinity(constraint.Width))
result.Width = (Child as FrameworkElement)?.MinWidth ?? 0.0;
return result;
}
}
如果这对您有帮助或您有任何反馈,请告诉我。
我有一个 HorizontalScrollBarVisibility 设置为 "Auto" 的 ScrollViewer,其中包含一个 TextBox。问题在于,当用户输入文本时,TextBox 会不断增长以显示全部内容。我需要更改什么,以便 TextBox 仅获取可用宽度(但不小于给定的最小宽度)?
仅当可用水平滚动条 space 不足以满足给定的最小宽度时,才应显示水平滚动条。
只有当有更多水平 space 可用时,TextBox 才应该增长。
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*" MinWidth="50"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Text="test:"/>
<TextBox Grid.Column="1"/>
</Grid>
</ScrollViewer>
即使满足 MinWidth 约束,水平滚动条也会出现:
这似乎是一个普遍的问题,但我还没有在网上找到满意的解决方案。
这是我的解决方案:
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*" MinWidth="100"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Text="test:"/>
<local:TextBoxDecorator Grid.Column="1">
<TextBox Text="content content content content content content"/>
</local:TextBoxDecorator>
</Grid>
</ScrollViewer>
c#
public class TextBoxDecorator : Decorator {
// properties
public override UIElement Child {
get {
return base.Child;
}
set {
var oldValue = base.Child;
if (oldValue != null) {
var binding = BindingOperations.GetBinding(oldValue, FrameworkElement.WidthProperty);
if ((binding != null) && (binding.Source == this))
BindingOperations.ClearBinding(oldValue, FrameworkElement.WidthProperty);
}
base.Child = value;
if ((value != null) &&
BindingOperations.GetBinding(value, FrameworkElement.WidthProperty) == null)
BindingOperations.SetBinding(
value,
FrameworkElement.WidthProperty,
new Binding() {
Source = this,
Path = new PropertyPath(FrameworkElement.ActualWidthProperty),
Mode = BindingMode.OneWay
});
}
}
// methods
protected override Size MeasureOverride(Size constraint) {
Size result = base.MeasureOverride(constraint);
if (double.IsInfinity(constraint.Width))
result.Width = (Child as FrameworkElement)?.MinWidth ?? 0.0;
return result;
}
}
如果这对您有帮助或您有任何反馈,请告诉我。