Wpf 如何强制网格收缩包含ScrollViewer的自动大小的行(需要时)?

Wpf 如何强制网格收缩包含ScrollViewer的自动大小的行(需要时)?,wpf,layout,grid,scrollviewer,Wpf,Layout,Grid,Scrollviewer,如何创建此布局 其想法是将蓝色文本始终保持在绿色元素的正下方,但当没有足够的空间时,绿色元素应放置在可滚动的容器中(垂直滚动条可见) 我试过StackPanel和Grid,但都失败了。StackPanel根本不收缩行。如果顶层行定义的高度设置为“自动”(内部的ScrollViewer不显示其滚动条),网格也会执行相同的操作。如果设置为星形,则蓝色文本将下移到至少一半的空间(取决于底部行的高度设置)。底部行的高度可以是“自动”或星形,蓝色文本的垂直对齐设置为顶部,但行的高度必须至少与文本的高度一

如何创建此布局

其想法是将蓝色文本始终保持在绿色元素的正下方,但当没有足够的空间时,绿色元素应放置在可滚动的容器中(垂直滚动条可见)

我试过StackPanel和Grid,但都失败了。StackPanel根本不收缩行。如果顶层行定义的高度设置为“自动”(内部的ScrollViewer不显示其滚动条),网格也会执行相同的操作。如果设置为星形,则蓝色文本将下移到至少一半的空间(取决于底部行的高度设置)。底部行的高度可以是“自动”或星形,蓝色文本的垂直对齐设置为顶部,但行的高度必须至少与文本的高度一样大。当然,整个区域(黑匣子)不能被其内容拉伸——它由窗口的大小决定

怎么做?如果可能,请保留基于XAML的回复。


<Grid Name="outerGrid">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"></RowDefinition>
        <RowDefinition Height="*"></RowDefinition>
    </Grid.RowDefinitions>

    <Canvas>
        <Grid MaxWidth="{Binding ElementName=outerGrid, Path=ActualWidth}" MaxHeight="{Binding ElementName=outerGrid, Path=ActualHeight}">
            <Grid.RowDefinitions>
                <RowDefinition Height="*"></RowDefinition>
                <RowDefinition Height="Auto"></RowDefinition>
            </Grid.RowDefinitions>
            <ScrollViewer Width="{Binding ElementName=outerGrid, Path=ActualWidth}">
                <TextBlock TextWrapping="Wrap">In this case the element is too big to fit inside whole space (the black box) with the blue text below. I want the scrollbar to be shown instead of moving the blue text outside of the black box (and clipped)</TextBlock>
            </ScrollViewer>
            <TextBlock TextWrapping="Wrap" Grid.Row="1">Automatically wrapped text of unknown length.</TextBlock>
        </Grid>
    </Canvas>
</Grid>
在这种情况下,元素太大,无法容纳下面蓝色文本的整个空间(黑框)。我希望显示滚动条,而不是将蓝色文本移出黑框(并剪裁) 自动包装长度未知的文本。
自动高度将增长,以匹配该行内容的高度

星形高度将使该行的高度增加,以填充网格的其余高度,从而防止
ScrollViewer
的增长超过可见的高度

编辑:如果将网格放在另一个网格(如上面的XAML)中,则应获得所需的行为。 外部行的第二行用作“填充”以填充外部网格的其余空间

编辑2:尝试上面编辑的XAML。我已将内部
网格
放入
画布
(以防止剪切)并将内部
网格的
MaxWidth
MaxHeight
绑定到外部
网格的
实际宽度和
实际高度,以保持内部
网格的大小与外部
网格的大小相同


编辑3:在
ScrollViewer
宽度上添加了绑定,使其与其余部分保持相同的宽度。

受Eirik通过将贪婪容器放入其他紧凑容器来约束贪婪容器的方法启发,我发现了一种实现我想要的东西的非常简单的方法。我只需要一个容器,首先收缩它的一个子容器,然后(当第一个子容器完全消失时)收缩第二个子容器。还有这样的容器:DockPanel。下面是:

<DockPanel LastChildFill="False">
    <DockPanel DockPanel.Dock="Top">
        <TextBlock DockPanel.Dock="Bottom" TextWrapping="Wrap" Grid.Row="1">Automatically wrapped text of unknown length.</TextBlock>
        <ScrollViewer>
            <TextBlock TextWrapping="Wrap">In this case the element is too big to fit inside whole space (the black box) with the blue text below. I want the scrollbar to be shown instead of moving the blue text outside of the black box (and clipped)</TextBlock>
        </ScrollViewer>
    </DockPanel>
</DockPanel>

自动包装长度未知的文本。
在这种情况下,元素太大,无法容纳下面蓝色文本的整个空间(黑框)。我希望显示滚动条,而不是将蓝色文本移出黑框(并剪裁)

就这么简单!:)我希望它能帮助别人。

这会很好,但我希望底部(蓝色)文本放在上部元素的正下方(尽可能高)。在您的示例中,它被放置在窗口(网格)的底部。我希望文本下方有空闲空间。这种方法看起来不错,但你测试过吗?不幸的是,它不起作用。这一次,当您缩小整个窗口(因此没有足够的空间)时,控件将被剪裁。内桌没有缩水。我猜当行设置为“自动”(本例中为外部表)时,它将永远不会缩小,即使它比整个表大。你看,事情并不是那么简单。PS:我想我会立即得到正确的答案,因为在WPF中任何事情都可以做。。。这里有很多专家,但看起来WPF并不像人们所说的那样灵活。在这种情况下,它几乎可以工作,但ScrollViewer的宽度(水平拉伸窗口时)会跳跃,以匹配包装文本后内容文本的实际宽度。这意味着滚动条不会随着窗口边框向右移动,直到下一个单词可以对齐为止。我已尝试将“水平对齐”设置为“拉伸”,但没有任何帮助。@P.W.请参阅编辑3以修复跳跃的
ScrollViewer
width。这一项最终按预期工作!:)然而与此同时,我发现了更简单的解决方案。我马上附上答复。没有你我做不到,所以我给你+1:)谢谢!这确实帮助了我。我试着做完全相同的事情,这很有魅力。感谢您提出最终解决方案!