ListView с WrapPanel - как сделать VerticalScrollBar?

349
09 декабря 2016, 08:56

Имеется ListView следующего вида:

<ListView ItemsSource="{Binding ListItems}" Grid.Row="1" 
            SelectedItem="{Binding SelectedItem, Mode=TwoWay}" 
            ScrollViewer.HorizontalScrollBarVisibility="Disabled" 
            ScrollViewer.VerticalScrollBarVisibility="Auto" >
    <ListView.ItemTemplate>
        <DataTemplate>
            <!-- шаблон в виде прямоугольника с картинкой и текстом -->
        </DataTemplate>
    </ListView.ItemTemplate>
    <ListView.ItemContainerStyle>
        <!-- покраска -->
    </ListView.ItemContainerStyle>
    <ListView.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ListView.ItemsPanel>
</ListView>

ListView помещён в Grid, высота строки "*".

Проблема заключается в том, что когда элементов становится достаточно много, VerticalScrollBar не появляются, и новые элементы продолжают вертикально растягивать ListView.

Пробовал отключать HorizontalScrollBarVisibility, помещать ListView в ScrollViewer - не помогает. Если добавить MaxHeight="{Binding ListHeight}" - работает, но при растягивании окна ListView остаётся того же размера, что и был (нужно, чтобы оно растягивалось).

Вопрос: как заставить появиться вертикальную прокрутку?

Answer 1

Нашёл (в определённой степени довольно корявое) решение:

В ViewModel к этому UserControl добавил следующее:

// в конструктор
Application.Current.Windows[0].SizeChanged += new SizeChangedEventHandler(Window_SizeChanged);
// свойство, к которому привязан MaxHeight
public int ListHeight
{
    get
    {
        return (int)Application.Current.Windows[0].ActualHeight - _restHeight;
    }
}
// принуждение ListHeight к обновлению
private void Window_SizeChanged(object sender, System.Windows.SizeChangedEventArgs e)
{
    NotifyPropertyChanged("ListHeight");
}
Answer 2

Для достижения аналогичной цели я задавал такой ItemsPanelTemplate в ListView.ItemsPanel

<ListView.ItemsPanel >
    <ItemsPanelTemplate>
        <WrapPanel
            ScrollViewer.HorizontalScrollBarVisibility="Disabled"
            HorizontalAlignment="Stretch"
            Orientation="Horizontal"
            Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
                            AncestorType={x:Type ListView}}, Path=ActualWidth}"/>
    </ItemsPanelTemplate>
</ListView.ItemsPanel>

UPD:

Обратите внимания на свойство Width в WrapPanel оно привязывается к свойству ActualWidth в ListView. При изменении размера ListView будет меняться размер WrapPanel.

READ ALSO
Как в C# обходились, когда не было Dynamic?

Как в C# обходились, когда не было Dynamic?

Например, из вне приходит какой-то объект неизвестного типа

311
Стиль контролов в WPF

Стиль контролов в WPF

Уже третий день бьюсьНаписал триггер для кнопки:

323
Получить привязанный объект из DataGridViewComboBoxCell

Получить привязанный объект из DataGridViewComboBoxCell

У стандартного ComboBox есть свойство SelectedValue, которое можно привести к привязанному типу и получить значение из поля, которое не отображается...

308
пару строчек из C# в Java

пару строчек из C# в Java

Подскажите пожалуйста, как этот метод поиска переписать на Java?

303