WPF不支持Textbox.MinLines进行自动高度计算

时间:2009-05-06 18:06:53

标签: wpf user-interface xaml layout textbox

我希望有一个TextBox,当我输入文本行时,Height会增长。

我已将Height属性设置为“Auto”,并且到目前为止还在增长。 现在我希望TextBox的高度应该至少为5行。 现在我将MinLines属性设置为“5”但是如果我启动应用程序,TextBox的高度仍然是一行。

3 个答案:

答案 0 :(得分:2)

尝试设置MinHeight属性。

答案 1 :(得分:1)

使MinLines属性工作的黑客

public class TextBoxAdv : TextBox
{
    bool loaded = false;


    /// <summary>
    /// Constructor
    /// </summary>
    public TextBoxAdv()
    {
        Loaded += new RoutedEventHandler( Control_Loaded );

        SetResourceReference( StyleProperty, typeof( TextBox ) );
    }


    void Control_Loaded( object sender, RoutedEventArgs e )
    {
        if( !loaded )
        {
            loaded = true;

            string text = Text;
            Text = "Text";
            UpdateLayout();
            Text = text;
        }
    }
}

答案 2 :(得分:0)

我提出了另一种解决方案,该解决方案应适当尊重MinLines属性,而不是强迫您使用MinHeight

首先,从方便的方法开始,允许您Post对窗口循环执行操作。 (我同时包括需要传递状态的一个和不需要传递状态的一个。)

public static class Globals {

    public static void Post(Action callback){

        if(SynchronizationContext.Current is SynchronizationContext currentContext)
            currentContext.Post( _ => callback(), null);
        else{
            callback();
        }
    }

    public static void Post<TState>(TState state, Action<TState> callback){

        if(SynchronizationContext.Current is SynchronizationContext currentContext)
            currentContext.Post(_ => callback(state), null);
        else{
            callback(state);
        }
    }
}

接下来,为TextBox创建一个扩展方法,以基于MinLines“初始化”适当的大小。我将其放在Hacks类中,因为对我来说就是这样,并且可以清楚地标识出这样的代码。

public static void FixInitialMinLines(this TextBox textBox) {

    Globals.Post(() => {

        var textBinding = textBox.GetBindingExpression(TextBox.TextProperty)?.ParentBinding;

        if (textBinding != null) {
            BindingOperations.ClearBinding(textBox, TextBox.TextProperty);
            textBox.UpdateLayout();
            BindingOperations.SetBinding(textBox, TextBox.TextProperty, textBinding);
        }
        else {
            var lastValue = textBox.Text;
            textBox.Text = lastValue + "a";
            textBox.UpdateLayout();
            textBox.Text = lastValue;
        }
    });
}

上面的代码处理绑定和未绑定的TextBox控件,而不是像其他控件那样简单地更改值,这些控件可能会通过绑定进行级联更改,而是首先断开绑定,强制布局,然后重新连接绑定,从而触发UI中的正确布局。这样可以避免在绑定是双向的情况下无意更改绑定源。

最后,只需为设置了TextBox的每个MinLines调用扩展方法。由于扩展方法中的Post调用,您可以在InitializeComponent之后立即调用此方法,并且在触发所有其他事件(包括所有布局和Loaded事件)后,该方法仍将执行。

public partial class Main : Window {

    public Main() {

        InitializeComponent();

        // Fix initial MinLines issue
        SomeTextBoxWithMinLines.FixInitialMinLines();
    }

    ...
}

将上述代码添加到函数的“库”中,然后可以在所有窗口和控件中使用单行代码来解决该问题。享受吧!