阻止ScrollViewer中的TextBox随着内容的增长而停止

时间:2015-06-17 01:49:18

标签: wpf wpf-controls

我有一个ScrollViewer,其Horizo​​ntalScrollBarVisibility设置为“Auto”,其中包含一个TextBox。问题是当用户输入文本时,TextBox会不断增长以显示整个内容。我需要更改什么,以便TextBox只抓取可用的宽度(但不小于给定的最小宽度)?

仅当可用的水平空间不足以满足给定的最小宽度时,才会出现水平滚动条。

只有在有更多可用的水平空间时,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约束,也会出现水平滚动条:

enter image description here

1 个答案:

答案 0 :(得分:0)

这似乎是一个常见的问题,但我还没有在网上找到令人满意的解决方案。

这是我的解决方案:

<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;
    }
}

如果这有用,或者您有任何反馈,请告诉我。