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

Posted

技术标签:

【中文标题】将 WPF 控件设置为扩展以填充可用空间,仅此而已【英文标题】:Setting a WPF control to expand to fill available space, and no more 【发布时间】:2010-11-21 16:10:27 【问题描述】:

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

以下 sn-p 描述了我正在尝试的布局。我希望Grid 可以拉伸以容纳Expander,我希望ListBox 仅填充Grid。当Grid 太小而无法显示所有ListBoxItems 时,我希望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 太大而无法显示在屏幕上时出现外部滚动条。

【问题讨论】:

【参考方案1】:

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

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 中没有作为选项出现。【参考方案2】:

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 太大而无法显示在屏幕上的情况。 扩展器内容是什么?这就是您应该确保存在 ScrollViewer 的地方。 我希望整个 UserControl 滚动,包括这里没有包含的一些内容,所以我不能在 Expander 周围移动 ScrollViewer

以上是关于将 WPF 控件设置为扩展以填充可用空间,仅此而已的主要内容,如果未能解决你的问题,请参考以下文章

如何使wpf数据网格填充所有可用空间并使用窗口调整大小?

WPF:如何使控件在 StackPanel 中拉伸?

WPF:将控件高度设置为填充网格行高

WPF 格式化文本:计算字体大小以填充可用高度空间

如何设置 p-tree 的宽度以填充可用空间?

如何使 DockPanel 中的项目扩展以适应 WPF 中的所有可用空间?