Setting a WPF control to expand to fill available space, and no more

醉酒当歌 提交于 2019-12-06 11:15:49

问题


How can I set up a WPF control to fill the available space in its parent's container, but not expand the parent?

The following snippet describes the layout I am attempting. I would like the Grid to stretch to accommodate the Expander, and I would like the ListBox only to fill the Grid. I want the ListBox's scroll bar to appear when the Grid is too small to show all the ListBoxItems.

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

Currently what happens is that the Grid stretches to fit the entire ListBox, and the outer ScrollViewer's vertical scroll bar appears. I only want the outer scroll bar to appear when the Expander gets too big to fit on screen.


回答1:


To solve the same problem I wrote special container class:

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

Surround your ListBox by the container and the height of ListBox will be the same as of 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>

Note that I remove Width="Auto" from column's definition because the FrugalContainer will be as small as it can. So you can't set the width or height of the parent grid's cell to Auto.

If you need autosizing, rewrite the container:

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



回答2:


What is the point of the ScrollViewer? Just let the ScrollViewer in the ListBox template appear naturally when too little room is available.

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


来源:https://stackoverflow.com/questions/1312043/setting-a-wpf-control-to-expand-to-fill-available-space-and-no-more

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!