简体   繁体   English

垂直调整StackPanel的大小以适合其内容

[英]Vertically resize StackPanel to fit around its contents

I have a textbox inside a StackPanel and the TextBox is set to AcceptsReturn , so when you press the Enter/Return key the textbox will become bigger in height. 我在StackPanel有一个文本框,并且TextBox设置为AcceptsReturn ,所以当您按Enter / Return键时,文本框的高度会变大。

The problem I'm having is that I don't know how to make the surrounding StackPanel change in height along with the textbox. 我遇到的问题是我不知道如何使周围的StackPanel以及文本框的高度发生变化。 So when the textbox changes, so should the StackPanel . 因此,当文本框更改时, StackPanel应更改。

How can we do this? 我们应该怎么做?

    <GridView x:Name="texties" Grid.Row="1" Margin="120, 0, 0, 0" ItemsSource="{Binding Something, Mode=TwoWay}" SelectionMode="Multiple">
        <GridView.ItemTemplate>
            <DataTemplate>
                <StackPanel Margin="10" Orientation="Vertical" Width="210" >
                    <StackPanel.ChildrenTransitions>
                        <TransitionCollection>
                            <AddDeleteThemeTransition/>
                        </TransitionCollection>
                    </StackPanel.ChildrenTransitions>
                    <TextBlock Text="{Binding Name, Mode=TwoWay}" FontWeight="Bold" Style="{StaticResource ItemTextStyle}" />
                    <TextBox Text="{Binding Content, Mode=TwoWay}" FontSize="12" Background="{x:Null}" BorderBrush="{x:Null}" BorderThickness="0, 0, 0, 0" AcceptsReturn="True" IsSpellCheckEnabled="True" />
                </StackPanel>
            </DataTemplate>
        </GridView.ItemTemplate>
    </GridView>

Based on your sample you are not setting the GridView.ItemsPanel . 根据您的示例,您没有设置GridView.ItemsPanel The default value of GridView.ItemsPanel is <WrapGrid /> which has a set cell size that cannot be changed. GridView.ItemsPanel的默认值为<WrapGrid /> ,其设置的单元格大小无法更改。 You might be tempted to update to <VariableSizedWrapGrid /> but this control cannot change span values except during render. 您可能会想更新到<VariableSizedWrapGrid />但是此控件无法更改跨度值,除非在渲染期间。 If what you want is even possible, it will require that you use <StackPanel/> as your GridView.ItemsPanel . 如果您想要的甚至是可能的,则要求您使用<StackPanel/>作为GridView.ItemsPanel However, <StackPanel/> does not wrap natively, so you will either need to locate a wrapping version someone else has made, make your own, or live with it in a single row or column. 但是, <StackPanel/>并不是本机包装的,因此您将需要找到其他人制作的包装版本,自己制作包装版本或将其放在一行或一列中。

Some developers attempt to change the size of their template based on the height of their <TextBlock /> . 一些开发人员尝试根据其<TextBlock />的高度来更改模板的大小。 This is a good idea but a difficult tech to execute. 这是一个好主意,但执行起来却很困难。 It turns out that the size of a UI Element is not determined until it is rendered and so you have to render it first, and then it is too late. 事实证明,UI元素的大小直到渲染后才确定,因此您必须先渲染它,然后为时已晚。 If you want to see how one developer has accomplished this calculation (consider the difficulty of font-family and font-size and margin, etc) look here . 如果您想了解一位开发人员是如何完成此计算的(请考虑字体家族的难度以及字体大小和边距等),请参见此处 Such a calc would allow you to use <VariableSizedWrapGrid /> . 这样的计算将允许您使用<VariableSizedWrapGrid />

In this sample he is calculating for an ellipse, but it's ~the same calculation. 在此示例中,他正在计算一个椭圆,但这是相同的计算。

protected override Size MeasureOverride(Size availableSize)
{
    // just to make the code easier to read
    bool wrapping = this.TextWrapping == TextWrapping.Wrap;


    Size unboundSize = wrapping ? new Size(availableSize.Width, double.PositiveInfinity) : new Size(double.PositiveInfinity, availableSize.Height);
    string reducedText = this.Text;


    // set the text and measure it to see if it fits without alteration
    if (string.IsNullOrEmpty(reducedText)) reducedText = string.Empty;
    this.textBlock.Text = reducedText;
    Size textSize = base.MeasureOverride(unboundSize);


    while (wrapping ? textSize.Height > availableSize.Height : textSize.Width > availableSize.Width)
    {
        int prevLength = reducedText.Length;

        if (reducedText.Length > 0)
            reducedText = this.ReduceText(reducedText);    

        if (reducedText.Length == prevLength)
            break;

        this.textBlock.Text = reducedText + "...";
        textSize = base.MeasureOverride(unboundSize);
    }

    return base.MeasureOverride(availableSize);
}

Best of luck. 祝你好运。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM