Raymond Osterbrink
Raymond Osterbrink

Reputation: 540

How to create a horizontal scrolling image grid in wpf

I'm trying to implement an Image-Overview in my WPF-Application. For now, I've all Images beneath each other, with the opportunity to scroll verticaly, but I need them inside an horizontal scrolling grid of 3x(n/3) Images, where n is the total amount of images.

<UserControl.Resources>
    <Style TargetType="{x:Type ListBox}">
        <Setter Property="ItemTemplate">
            <Setter.Value>
                <DataTemplate>
                    <Border BorderBrush="Black" BorderThickness="4" CornerRadius="5" Margin="6" >
                        <Image Source="{Binding Path=UriSource}" Stretch="Fill" Width="100" Height="120" />
                    </Border>
                </DataTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</UserControl.Resources>

<UserControl.DataContext>
    <ObjectDataProvider ObjectType="{x:Type local:FileCollection}" MethodName="LoadImages" />
</UserControl.DataContext>

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="40"/>
    </Grid.RowDefinitions>

    <ListBox ItemsSource="{Binding}" Grid.ColumnSpan="3" />
</Grid>

Actual Orientation is:

H
H
H
.
.
.

After I followed pushprajs advice its:

HHH...

What i like to see is this:

HHHH
HHH
HHH

And again with real images:

how it looks for now:

how it looks for now

what i'd like to see:

what i'd like to see

Upvotes: 1

Views: 1494

Answers (1)

pushpraj
pushpraj

Reputation: 13669

here you go

<ListBox ItemsSource="{Binding}"
         Grid.ColumnSpan="3">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal" />
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
</ListBox>

Idea is to change the items panel to a stack panel with horizontal orinetation

3 rows across->vertical layout

<ListBox ItemsSource="{Binding}"
         Grid.ColumnSpan="3">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Rows="3" />
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
</ListBox>

3 row vertical->across layout

this is bit complex

<Grid xmlns:l="clr-namespace:CSharpWPF">
    <Grid.Resources>
        <l:CollectionSplitter x:Key="CollectionSplitter" />
    </Grid.Resources>
    <ListBox Grid.ColumnSpan="3"
             ItemsSource="{Binding Collection,Converter={StaticResource CollectionSplitter}}">
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal" />
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
        <ListBox.ItemTemplate>
            <DataTemplate>
                <ItemsControl ItemsSource="{Binding}">
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <UniformGrid Columns="1"
                                         Rows="3" />
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <Border BorderBrush="Black"
                                    BorderThickness="4"
                                    CornerRadius="5"
                                    Margin="6">
                                <Image Source="{Binding Path=UriSource}"
                                       Stretch="Fill"
                                       Width="100"
                                       Height="120" />
                            </Border>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

for above you need a converter as well

namespace CSharpWPF
{
    class CollectionSplitter:IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            List<IEnumerable<object>> result = new List<IEnumerable<object>>();
            IEnumerable<object> collection = (value as IEnumerable).OfType<object>();
            for (int i = 0; i < collection.Count(); i+=3)
            {
                result.Add(collection.Skip(i).Take(3));
            }
            return result;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

result

result

Upvotes: 2

Related Questions