将WPF控件设置为自动填充可用空间,但不超过这个范围

6

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

以下代码片段描述了我正在尝试的布局。我希望Grid能够伸展以适应Expander,并且我只想让ListBox填充Grid。当Grid太小无法显示所有ListBoxItem时,我希望ListBox的滚动条出现。

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

目前的情况是Grid会被拉伸以适应整个ListBox,并且外部ScrollViewer的垂直滚动条出现。我只希望当Expander过大无法在屏幕上显示时才出现外部滚动条。

2个回答

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

将您的ListBox放在容器中,ListBox的高度将与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>

请注意,我从列的定义中删除了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;
    }
}

我觉得问这个有点蠢,但是你把这个自定义装饰器类放在哪里?我把它放在了应用程序根目录,但在 Xaml 中没有出现选项。 - Kyeotic
非常优雅的解决方案,比将 ListBox 的 MaxHeight 绑定到父容器的 ActualHeight 更好,而这也是目前最广泛推荐的解决方案。 - dmg

0

ScrollViewer的作用是什么?当可用空间不足时,只需让ListBox模板中的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>

外部滚动查看器用于当 Expander 太大而无法在屏幕上容纳时。 - sourcenouveau
扩展器内容是什么?这就是你应该确保存在一个ScrollViewer的地方。 - Kent Boogaart
我希望整个UserControl可以滚动,包括一些未在此处包含的内容,因此我无法将ScrollViewer移动到Expander周围。 - sourcenouveau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接