如何使WPF ListView的高度与内容相等并适应窗口大小,同时还有其他控件?

19

我正在尝试安排一个WPF用户界面,如下所示:

Mock up

  1. 窗口顶部有一些自主高度控件(实际上是停靠在窗口顶部,但高度可以任意设置)。
  2. 在这些控件下面是一个ListView。ListView 可能包含数量不定的项,每个项的高度也可能不同。问题是:ListView 的高度不能超过所需高度。如果列表视图中的所有项都可以轻松适应窗口大小,我希望 ListView 的高度恰好足以显示其所有项(因此窗口看起来像网页的流动布局,在底部留有空白)。另一方面,如果所有 ListView 项无法适应窗口大小,我希望整个 UI 能够适应窗口大小(就像下面的第三个内容停靠在窗口底部,而 ListView 填充了可用空间)。所有这些都必须根据用户调整窗口大小和/或按下更改列表视图内容的按钮进行动态调整。
  3. 在 ListView 下面还有一些自主高度控件。这些控件必须始终直接出现在 ListView 下面,没有间隙。特别是,如果它们可以直接放在 ListView 下面,它们不能只停靠在窗口底部。

非常欢迎提供解决方案;我已经尝试了一段时间,并设法使事情正常工作,但是除了使用窗口中的外部 DockPanel 并将第一个控件停靠在顶部以外,ListView 填充其余空间但设置为 VerticalAlignment="Top" 以外,下面的控件无法正常显示。

如果可以的话,一个纯XAML的解决方案是最理想的,但如果避免不了的话我也不介意使用代码后台。如果能提供一种允许多个这样的排列垂直堆叠的解决方案,那就更好了:) 感谢任何帮助!

4个回答

18

尝试一下

<Grid VerticalAlignment="Top">
    <Grid.RowDefinitions>
        <RowDefinition Height="auto" />
        <RowDefinition Height="*" />
        <RowDefinition Height="auto" />

    </Grid.RowDefinitions>

    <Button Content="hello" />
    <ScrollViewer Grid.Row="1" >
    <ListView >
            <ListBoxItem Content="hi" />
            <ListBoxItem Content="hi" />
            <ListBoxItem Content="hi" />
            <ListBoxItem Content="hi" />
            <ListBoxItem Content="hi" />
            <!-- Some Items -->
    </ListView>
    </ScrollViewer>
    <Button Content="hello" Grid.Row="2" />

</Grid>

2
太简单了!而且正是我想要的。Grid上的VerticalAlignment="Top"似乎是关键,我完全没有想到,但非常合理。(编辑:我不需要ScrollViewer,ListView会自动滚动并适应得很好。)非常感谢。 - El Zorko
你在虚拟化方面处于劣势。 - Shahar Prish
1
如果您移除ScrollViewer,滚动效果会更好。ListView内置了一个ScrollViewer。请参阅https://dev59.com/rWox5IYBdhLWcg3w1X2- - brinkdinges

1
使用三行的网格(Grid),将所有三个行的高度设置为Auto,以便它们根据内容自动调整大小。
<Window x:Class="WpfApplicationUnleashed.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:local="clr-namespace:WpfApplicationUnleashed"
        Title="Window1" >
    <Grid VerticalAlignment="Top">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
        </Grid.RowDefinitions>

        <StackPanel Margin="10" Grid.Row="0" Orientation="Horizontal">
            <Button Margin="10">These are top controls</Button>
            <Label Margin="10">These are top controls</Label>
            <TextBox Margin="10">These are top controls</TextBox>
        </StackPanel>

        <TreeView Margin="10" Grid.Row="1">
            <TreeViewItem Header="Item 1" >
                <TreeViewItem Header=" Sub Item 1" />
                <TreeViewItem Header=" Sub Item 2" />
                <TreeViewItem Header="Sub Item 3" />
            </TreeViewItem>
            <TreeViewItem Header="Item 2" />
            <TreeViewItem Header="Item 3" />
            <TreeViewItem Header="Item 4" />
        </TreeView>

        <StackPanel Margin="10" Grid.Row="2" Orientation="Horizontal">
            <Button Margin="10">These are bottom controls</Button>
            <Label Margin="10">These are bottom controls</Label>
            <TextBox Margin="10">These are bottom controls</TextBox>
        </StackPanel>


    </Grid>
</Window>

1
遗憾的是,这不会使列表框的大小符合我的要求(只有在需要时才会尽可能小地适应窗口大小)。结果是ListBox的大小将变得像它想要的那样大,这导致它没有滚动条,而且底部自适应控件也不可见。 - El Zorko
我在发布代码时晚了几秒钟,我还将VerticalAlignment设置为Top。 - Akshay J
在那种情况下,为该键设置+1,非常感谢您的回答。 - El Zorko

1

我也曾遇到过大小的问题,解决方法是设置表格行的高度属性。我的设置如下:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"></RowDefinition>
        <RowDefinition Height="Auto"></RowDefinition>
    </Grid.RowDefinitions>
    <ListBox Grid.Row="0"
                         HorizontalAlignment="Stretch"
                         VerticalContentAlignment="Stretch" 
                         ScrollViewer.CanContentScroll="True"
                         ScrollViewer.VerticalScrollBarVisibility="Visible"
                         ItemsSource="{Binding AuditEntries}"
                         Margin="1 0 1 1" BorderThickness="0" VerticalAlignment="Top"/>
    <Button Grid.Row="1" />
</Grid>

所以真正解决我的问题的方法是设置包含我的ListBox的第一行定义的Height属性:

<RowDefinition Height="*"></RowDefinition>

What jolly fun...


0

把列表视图和底部控件放到它们自己的堆栈面板中不就足够了吗?


我也曾这样想,但是要么它不起作用,要么我的执行有问题——当整个ListView加上其他控件适合窗口时,它的效果非常好,但如果必须使ListView更小,它就无法完成。我还玩过网格,但目前还没有成功。 - El Zorko

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