如何使WPF ListView不高于其内容但适合窗口与其他控件?

时间:2022-11-13 10:43:26

I'm trying to arrange a WPF UI as follows:

我正在尝试按如下方式安排WPF UI:

如何使WPF ListView不高于其内容但适合窗口与其他控件?

  1. At top of the window are some controls of self-determining height (effectively docked to the top of the window, but as tall as they want to be).
  2. 在窗口的顶部是一些自我确定高度的控件(有效地停靠在窗口的顶部,但是他们想要的高度)。
  3. Beneath those controls is a ListView. The ListView may contain a variable number of items each of varying height. The problem: The ListView mustn't be taller than it needs to be. If all the items in the list view will easily fit into the window, I want the ListView to be exactly the height to show all its items (so the window looks like a web page's flowing layout with blank space at the bottom). On the other hand if all ListView items won't fit into the window, I want the whole UI to fit to the window (as if number 3 below was docked to the bottom of the window, and the ListView was filling the available space). This all has to adjust dynamically as the user resizes the window and/or presses buttons which change the list view's contents.
  4. 这些控件下面是ListView。 ListView可能包含可变数量的项目,每个项目的高度各不相同。问题:ListView不能高于它需要的高度。如果列表视图中的所有项目都很容易适合窗口,我希望ListView正好是显示其所有项目的高度(因此窗口看起来像一个网页的流动布局,底部有空白区域)。另一方面,如果所有ListView项目都不适合窗口,我希望整个UI适合窗口(好像下面的数字3停靠在窗口底部,并且ListView填充了可用空间) 。当用户调整窗口大小和/或按下改变列表视图内容的按钮时,这一切都必须动态调整。
  5. Beneath the ListView are some more controls of self-determining height. These must appear directly under the ListView at all times, with no gap. In particular they mustn't just dock to the bottom of the window if they'll fit directly under the ListView.
  6. 在ListView下面是一些自我确定高度的控件。这些必须始终直接出现在ListView下,没有间隙。特别是如果它们直接适合ListView,它们不能仅停靠在窗口的底部。

Solutions would be very welcome; I've fiddled for some time and managed to get things working except the controls beneath the ListView, by using an outer DockPanel in the window with the first controls docked to the top, and the ListView filling the remaining space but set to VerticalAlignment="Top".

解决方案将非常受欢迎;我已经摆弄了一段时间,并设法让除了ListView下面的控件之外的东西工作,通过在窗口中使用外部DockPanel,第一个控件停靠在顶部,ListView填充剩余空间但设置为VerticalAlignment =“最佳”。

A pure XAML solution would be ideal, but I don't mind code behind if it's unavoidable. Bonus points for a solution which allows multiple such arrangements to be stacked vertically :) Thanks for any help!

一个纯XAML解决方案是理想的,但如果它不可避免,我不介意代码背后。一个解决方案的奖励点,允许多个这样的安排垂直堆叠:)感谢您的帮助!

4 个解决方案

#1


15  

Try

尝试

<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


2  

Use Grid with three rows and set the height of all three to Auto so that they will size to content.

使用具有三行的网格并将所有三个的高度设置为自动,以便它们将大小为内容。

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

#3


1  

I struggled with the size, too. And the answer was really to set the Height Property of my Grid Rows. I have the following setup:

我也在努力克服这个规模。答案是真正设置我的网格行的高度属性。我有以下设置:

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

So what really solved my problem was to set the Height property of the first row definition (that contains my ListBox):

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

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

What jolly fun...

多么愉快......

#4


0  

Isn't it enough to just put the listview and the bottom controls into their own stackpanel?

仅仅将listview和底部控件放入他们自己的stackpanel是不够的?

#1


15  

Try

尝试

<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


2  

Use Grid with three rows and set the height of all three to Auto so that they will size to content.

使用具有三行的网格并将所有三个的高度设置为自动,以便它们将大小为内容。

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

#3


1  

I struggled with the size, too. And the answer was really to set the Height Property of my Grid Rows. I have the following setup:

我也在努力克服这个规模。答案是真正设置我的网格行的高度属性。我有以下设置:

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

So what really solved my problem was to set the Height property of the first row definition (that contains my ListBox):

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

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

What jolly fun...

多么愉快......

#4


0  

Isn't it enough to just put the listview and the bottom controls into their own stackpanel?

仅仅将listview和底部控件放入他们自己的stackpanel是不够的?