Использование WrapPanel и ScrollViewer для создания многоколоночного списка в WPF - PullRequest
4 голосов
/ 26 мая 2009

Я создаю простое LOB-приложение, которое загружает данные из файла XML и отображает их в списке с несколькими кнопками для редактирования.

В моей первой попытке все было в порядке, за исключением того, что список прокручивался вниз в один длинный столбец. Я бы предпочел, чтобы данные переносились так, чтобы внизу окна он начинал второй столбец и т. Д. - если вы изменяете размер окна, данные должны соответственно изменяться.

Во-первых, я просто поместил ListBox в ScrollViewer. Это не имело никакого значения.

Затем я добавил WrapPanel в ItemTemplate. На этом этапе я получил длинный ряд по горизонтали, но он никогда не переносился на второй ряд, несмотря на мою настройку ScrollViewer.HorizontScrollbar = disabled.

Я искал в Интернете различные блоги и форумы, но не вижу разницы между предложениями и моим кодом (см. Ниже). Любые советы будут высоко оценены.

<Window x:Class="MyApp.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="My App" Height="300" Width="400"
        FocusManager.FocusedElement="{Binding ElementName=eventsList}">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="auto" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
                <ScrollViewer Grid.Row="0" Grid.Column="0"     HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
            <ListBox Name="eventsList">
                <ListBox.ItemsPanel>
                    <ItemsPanelTemplate>
                        <WrapPanel />
                    </ItemsPanelTemplate>
                </ListBox.ItemsPanel>
            </ListBox>
        </ScrollViewer>

        <StackPanel Grid.Row="1" Grid.Column="0" Orientation="Horizontal"     HorizontalAlignment="Center" Visibility="Collapsed">
            <Button Name="action1Button" />
            <Button Name="action2Button" />
            <Button Name="action3Button" />
        </StackPanel>
    </Grid>
</Window>

Ответы [ 2 ]

30 голосов
/ 29 мая 2009

Похоже, что вы на правильном пути: замена ItemsPanelTemplate в ListBox на WrapPanel, установка ориентации WrapPanel в вертикальное положение и установка ScrollViewer.VerticalScrollBar в значение Disabled - все, что вам нужно сделать.

Это работает для меня:

<Window x:Class="ScrollingWrapPanel.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Grid>
        <ListBox ScrollViewer.VerticalScrollBarVisibility="Disabled">
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel IsItemsHost="True" Orientation="Vertical"/>
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
            <ListBoxItem>
                <Rectangle Width="80" Height="80" Margin="10" Fill="Red"/>
            </ListBoxItem>
            <ListBoxItem>
                <Rectangle Width="80" Height="80" Margin="10" Fill="Orange"/>
            </ListBoxItem>
            <ListBoxItem>
                <Rectangle Width="80" Height="80" Margin="10" Fill="Yellow"/>
            </ListBoxItem>
            <ListBoxItem>
                <Rectangle Width="80" Height="80" Margin="10" Fill="Green"/>
            </ListBoxItem>
            <ListBoxItem>
                <Rectangle Width="80" Height="80" Margin="10" Fill="Blue"/>
            </ListBoxItem>
            <ListBoxItem>
                <Rectangle Width="80" Height="80" Margin="10" Fill="Indigo"/>
            </ListBoxItem>
            <ListBoxItem>
                <Rectangle Width="80" Height="80" Margin="10" Fill="Violet"/>
            </ListBoxItem>
        </ListBox>
    </Grid>
</Window>

Это должно заставить его визуализировать полный столбец по вертикали, обернуть и затем продолжить следующий столбец, прокручивая по мере необходимости по горизонтали (но не по вертикали), как на рисунке:

ListBox with WrapPanel wrapping vertically

Ключевыми моментами в этой реализации являются

  1. Установка Orientation = "Vertical" на WrapPanel так, чтобы вещи оборачивались вертикально, а не горизонтально, и
  2. Настройка ScrollViewer.VerticalScrollBarVisibility = "Disabled" в ListBox, чтобы ScrollViewer знал, как ограничить его высоту доступным пространством.
0 голосов
/ 26 мая 2009

Я полагаю, что для этого вам нужно написать собственный код - у вас есть правильная идея переопределить ItemsPanelTemplate, но WrapPanel не упорядочивает вещи так, как вы хотите - он упорядочивает вещи как:

A B C D
E F G H
I J K L

В то время как вы, вероятно, хотите это:

A D G J
B E H K
C F I L

Кроме того, если поместить его в ScrollViewer, это все равно, что сказать ему, что у него экран бесконечного размера, так что в результате получится всего одна строка (потому что ScrollViewer предоставит ему столько места, сколько ему нужно). Написание панели не сложно, это всего лишь две функции (Измерение и Расстановка).

...