Как сделать WPF ListView не выше его содержимого, но подходит к окну с другими элементами управления?

Я пытаюсь упорядочить интерфейс WPF следующим образом:

Mock up

  • В верхней части окна находятся некоторые элементы управления самоопределяющейся высотой (фактически прикрепленные к вершине окна, но такие высокие, как они хотят быть).
  • Под этими элементами управления находится ListView. ListView может содержать переменное количество элементов, каждый из которых имеет разную высоту. Проблема: ListView не должен быть выше, чем нужно. Если все элементы в представлении списка будут легко вписываться в окно, я хочу, чтобы ListView был точно высотой, чтобы показать все его элементы (поэтому окно выглядит как макет веб-страницы с пустым пространством внизу). С другой стороны, если все элементы ListView не будут вписываться в окно, я хочу, чтобы весь пользовательский интерфейс соответствовал окну (как будто номер 3 ниже было пристыковано к нижней части окна, и ListView заполнял доступное пространство). Все это должно динамически изменяться, когда пользователь изменяет размер окна и/или нажимает кнопки, которые изменяют содержимое списка.
  • Под списком ListView находятся некоторые элементы управления самоопределяющейся высотой. Они должны отображаться непосредственно под ListView во все времена, без пробелов. В частности, они не должны просто пристыковываться к нижней части окна, если они будут соответствовать непосредственно в ListView.

Решения будут очень приветствуемыми; Я поработал некоторое время и сумел заставить вещи работать кроме элементов управления под ListView, используя внешний DockPanel в окне с первыми элементами управления, прикрепленными к вершине, и ListView, заполняющим оставшиеся но установите значение VerticalAlignment = "Top".

Чистое решение XAML было бы идеальным, но я не против кода, если это неизбежно. Бонусные баллы за решение, которое позволяет собрать несколько таких устройств вертикально:) Спасибо за любую помощь!

Ответ 1

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

Используйте 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>

Ответ 3

Я тоже боролся с размером. И ответом было действительно установить свойство Height моих строк сетки. У меня есть следующая настройка:

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

Итак, что действительно решило мою проблему, было установить свойство Height для определения первой строки (содержащего мой ListBox):

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

Что весело...

Ответ 4

Не достаточно ли просто поместить элементы списка и нижние элементы управления в их собственную стеквую панель?