Using WrapPanel and ScrollViewer to give a multi-column Listbox in WPF

前端 未结 2 710
独厮守ぢ
独厮守ぢ 2021-01-01 03:52

I’m making a simple LOB app which loads data from an XML file and displays it in a list with a few buttons for editing.

In my first attempt, everything was ok except

相关标签:
2条回答
  • 2021-01-01 04:16

    It seems like you were on the right track: replacing the ItemsPanelTemplate in the ListBox with a WrapPanel, setting WrapPanel's Orientation to Vertical, and setting ScrollViewer.VerticalScrollBar to Disabled should be all you need to do.

    This works for me:

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

    That should cause it to render out a full column vertically, wrap, and then continue on the next column, scrolling as necessary horizontally (but not vertically), as in the picture:

    The key things in this implementation are

    1. Setting Orientation="Vertical" on the WrapPanel so that things wrap vertically and not horizontally, and
    2. Setting ScrollViewer.VerticalScrollBarVisibility="Disabled" on the ListBox so that the ScrollViewer knows to restrict its height to the available space.
    0 讨论(0)
  • 2021-01-01 04:31

    I believe to do this, you need to write custom code - you've got the right idea in overriding ItemsPanelTemplate, but WrapPanel doesn't order stuff the way you want it - it'll order stuff as:

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

    Whereas you probably want it:

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

    Also, by putting it in a ScrollViewer, it's like telling it that it has an infinitely sized screen, so the result will just be one row (because the ScrollViewer will give it as much room as it asks for). Writing a panel isn't hard, it's basically just two functions (Measure and Arrange).

    0 讨论(0)
提交回复
热议问题