Search code examples
wpflistviewuniformgrid

Best approach for WPF multi-column list view


I have a ListView with a lot of data (200+ items) so to save space it's making use of a UniformGrid to display 3 columns instead of 1

<ListView.ItemsPanel>
    <ItemsPanelTemplate>
        <UniformGrid Columns="3" />
    </ItemsPanelTemplate>
</ListView.ItemsPanel>

I also modify the style so that each item is aligned to the top

<ListView.Resources>
    <Style TargetType="{x:Type ListView}">
        <Setter Property="ItemContainerStyle">
            <Setter.Value>
                <Style TargetType="ListViewItem">
                    <Setter Property="VerticalContentAlignment" Value="Top"/>
                </Style>
            </Setter.Value>
        </Setter>
    </Style>
</ListView.Resources>

This works ok, however due to differences in the length of the data displayed, there is still wasted space in item groups because most of the data fits on a single line, but occasionally there is an item which takes up 2 or more rows. This means all rows in a group take up 2 or more rows when it's only 1 row that needs the extra space

alt text

Does anyone know how to fix this, or can suggest another approach to avoid the uniformgrid? Thanks!


Solution

  • You could use a vertical WrapPanel and disable vertical scrolling. That will cause the items to appear in columns with additional columns added on the right, similar to the list view in Windows Explorer. You can set Width or MaxWidth on the ListViewItems if you don't want a single line of long text to expand the entire column.

    <ListView ScrollViewer.VerticalScrollBarVisibility="Disabled">
        <ListView.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel Orientation="Vertical"/>
            </ItemsPanelTemplate>
        </ListView.ItemsPanel>
        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Setter Property="MaxWidth" Value="100"/>
            </Style>
        </ListView.ItemContainerStyle>
    

    You could use a normal Horizontal WrapPanel as well if you disable horizontal scrolling, although unless the elements are fixed width that will probably be awkward for the user.