Horizontal orientated WrapPanel within ItemsControl lists vertically

10,422

I think its because you are adding each image item to a new WrapPanel in GameImagesTemplate , you should just have to set the ItemsControl ItemsPanelTemplate to WrapPanel in the GameTemplate

Example:

Xaml:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="252.351" Width="403.213" Name="UI" >
    <Window.Resources>

        <DataTemplate x:Key="GameImagesTemplate" >
            <StackPanel>
                <Image Source="{Binding FileInfo.FullName}" Margin="8,8,8,8" Height="70" Width="70" />
                <Label Content="{Binding Name}" />
            </StackPanel>
        </DataTemplate>

        <DataTemplate x:Key="GameTemplate">
            <StackPanel>
                <Label Content="{Binding Name}" Grid.Row="0" Background="Gray" FontSize="16" />
                <ItemsControl x:Name="imageContent" ItemsSource="{Binding FileList}" ItemTemplate="{StaticResource GameImagesTemplate}" >
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <WrapPanel Orientation="Horizontal" ScrollViewer.HorizontalScrollBarVisibility="Disabled" />
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                </ItemsControl>
            </StackPanel>
        </DataTemplate>
    </Window.Resources>

    <Grid>
        <ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
            <ItemsControl ItemsSource="{Binding ElementName=UI, Path=FileList}" Grid.Column="0" ItemTemplate="{StaticResource GameTemplate}" />
        </ScrollViewer>
    </Grid>
</Window>

Code:

public partial class MainWindow : Window
{
    private ObservableCollection<Foo> _fileList = new ObservableCollection<Foo>();

    public MainWindow()
    {
        InitializeComponent();
        foreach (var item in Directory.GetDirectories(@"C:\StackOverflow"))
        {
            FileList.Add(new Foo
            {
                Name = item,
                FileList = new ObservableCollection<Bar>(Directory.GetFiles(item).Select(x => new Bar { FileInfo = new FileInfo(x) }))
            });
        }
    } 

    public ObservableCollection<Foo> FileList
    {
        get { return _fileList; }
        set { _fileList = value; }
    }
}

public class Foo
{
    public string Name { get; set; }
    public ObservableCollection<Bar> FileList { get; set; }
}

public class Bar
{
    public FileInfo FileInfo { get; set; }
}

Result

enter image description here

Share:
10,422
Jamie Keeling
Author by

Jamie Keeling

SOreadytohelp

Updated on July 24, 2022

Comments

  • Jamie Keeling
    Jamie Keeling almost 2 years

    I have two DataTemplates defined within my XAML, each used for a seperate ItemsControl panel.

    The main ItemsControl lists Foo objects stored within an ObservableCollection object.

    The Foo object itself has its own set of items stored within as an ObservableCollection object.

    I tried to define the XAML in a way that allows for each of the ObservableCollection Foo items to be displayed with its name in a header (The first ItemsControl). From this the list within each Foo item itself should be displayed horizontally (Using the second ItemsControl) with a related field directly below. If enough items are present then they should wrap to the next line where necessary.

    This is how the UI currently stands:

    Incorrect UI

    This is how I wish the UI to actually appear:

    Correct UI

    My Markup (Button controls are for another aspect of the UI) :

    <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
                <ItemsControl x:Name="ContentList" ItemTemplate="{StaticResource GameTemplate}" Grid.Column="0" />
            </ScrollViewer>
            <StackPanel Grid.Column="1" Background="DarkGray">
                <Button Click="OnLoad">_Load</Button>
                <Button Click="OnSave">_Save</Button>
                <Button Click="OnAdd">_Add</Button>
                <Button Click="OnDelete">_Delete</Button>
            </StackPanel>
        </Grid>
    

    DataTemplate for listing Foo items:

    <DataTemplate x:Key="GameTemplate">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="30" />
                        <RowDefinition Height="*" />
                    </Grid.RowDefinitions>
                    <Label Content="{Binding Name}" Grid.Row="0" Background="Gray" FontSize="16" />
                    <ItemsControl x:Name="imageContent" 
                                  ItemsSource="{Binding FileList}" 
                                  ItemTemplate="{StaticResource GameImagesTemplate}" 
                                  Grid.Row="1" />
                </Grid>
            </DataTemplate>
    

    DataTemplate for listing items within each Foo item:

    <DataTemplate x:Key="GameImagesTemplate">
                <WrapPanel Orientation="Horizontal">
                    <StackPanel Orientation="Vertical" >
                        <Image Source="{Binding FileInfo.FullName}" 
                           Margin="8,8,8,8" 
                           Height="70" 
                           Width="70" />
                        <Label Content="{Binding Name}" />
                    </StackPanel>
                </WrapPanel>
            </DataTemplate>
    

    I'm fairly new to WPF so I have a feeling it's an issue caused by how I am using the controls.

    What WPF changes would I need to make in order to generate the UI I would like?

  • Jamie Keeling
    Jamie Keeling about 11 years
    Ah, I see exactly where I was going wrong. Thank you for detailed answer - +1 and an accept for you!