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

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

Макет

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

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

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


person El Zorko    schedule 16.03.2011    source источник


Ответы (4)


Пытаться

<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>
person Elad Katz    schedule 16.03.2011
comment
Так просто! И именно то, что я хочу. То, что VerticalAlignment=Top on the Grid кажется ключом, на самом деле мне вообще не приходило в голову, но имеет смысл. (Редактировать: мне не нужен ScrollViewer, ListView прокручивается, если требуется, и прекрасно вписывается независимо.) Большое спасибо. - person El Zorko; 16.03.2011
comment
Однако здесь вы проигрываете виртуализации. - person Shahar Prish; 07.07.2018
comment
Если вы удалите scollviewer, прокрутка будет работать лучше. В Listview встроено средство просмотра прокрутки. См. stackoverflow.com/questions/8932720/ - person brinkdinges; 05.01.2021

Используйте сетку с тремя строками и установите для высоты всех трех строк значение «Авто», чтобы они соответствовали размеру содержимого.

<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>
person Akshay J    schedule 16.03.2011
comment
К сожалению, размер окна списка не такой, как я хочу (только настолько большой, насколько требуется, но меньше, чтобы соответствовать окну, если требуется). Это приводит к тому, что ListBox становится настолько большим, насколько ему хотелось бы, что приводит к тому, что у него нет полос прокрутки, а нижние элементы управления с автоматическим изменением размера не видны. - person El Zorko; 16.03.2011
comment
Я опоздал на несколько секунд с публикацией кода, я также установил для параметра VerticalALignment значение Top. - person Akshay J; 16.03.2011
comment
+1 за эту настройку ключа в таком случае, большое спасибо за ответ. - person El Zorko; 16.03.2011

Я тоже мучилась с размером. И ответ действительно состоял в том, чтобы установить свойство 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>

Какое веселое развлечение...

person anhoppe    schedule 27.02.2014

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

person coldandtired    schedule 16.03.2011
comment
Я тоже так думал, но либо это не работает, либо мое исполнение отстой - оно отлично работает, когда весь ListView плюс другие элементы управления помещаются в окне, но не уменьшает ListView, если это необходимо. Я тоже игрался с сетками, но пока безрезультатно. - person El Zorko; 16.03.2011