将 WPF 控件设置为扩展以填充可用空间,仅此而已

M. *_*ley 6 wpf height scroll autosize stretching

如何设置 WPF 控件来填充其父级容器中的可用空间,但不展开父级?

以下代码片段描述了我正在尝试的布局。我愿Grid伸以容纳Expander,我愿ListBox唯以填满Grid。我希望当太小而无法显示所有sListBox时,出现 的滚动条。GridListBoxItem

<ScrollViewer>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition />
        </Grid.RowDefinitions>
        <ListBox Grid.Row="0" Grid.Column="0" />
        <Expander Grid.Row="0" Grid.Column="1" Header="Expander" />
    </Grid>
</ScrollViewer>
Run Code Online (Sandbox Code Playgroud)

目前发生的情况是,Grid拉伸以适合整个ListBox,并且ScrollViewer出现了外部的垂直滚动条。我只希望当滚动条Expander变得太大而无法在屏幕上显示时出现。

Lu5*_*u55 5

为了解决同样的问题,我编写了特殊的容器类:

class FrugalContainer : Decorator
{
    protected override Size MeasureOverride(Size availableSize)
    {
        return new Size(0, 0);
    }

    protected override Size ArrangeOverride(Size arrangeSize)
    {
        // get it all
        Child.Measure(arrangeSize);
        Child.Arrange(new Rect(arrangeSize));
        return Child.RenderSize;
    }
}
Run Code Online (Sandbox Code Playgroud)

用容器包围列表框,列表框的高度将与 Expander 的高度相同。

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition />
    </Grid.RowDefinitions>
    <FrugalContainer Grid.Row="0" Grid.Column="0" >
        <ListBox />
    </FrugalContainer>
    <Expander Grid.Row="0" Grid.Column="1" Header="Expander" />
</Grid>
Run Code Online (Sandbox Code Playgroud)

请注意,我Width="Auto"从列的定义中删除,因为 FrugalContainer 将尽可能小。所以你不能将父网格单元格的宽度或高度设置为自动。

如果需要自动调整大小,请重写容器:

class FrugalHeightContainer : Decorator
{
    protected override Size MeasureOverride(Size availableSize)
    {
        Child.Measure(availableSize);
        return new Size(Child.DesiredSize.Width, 0);
    }

    protected override Size ArrangeOverride(Size arrangeSize)
    {
        Child.Measure(arrangeSize);
        Child.Arrange(new Rect(arrangeSize));
        return Child.RenderSize;
    }
}
Run Code Online (Sandbox Code Playgroud)