Austin Henley
Austin Henley

Reputation: 4633

Layout to use for dynamic grid of images in a ScrollViewer

I have a ScrollViewer that contains a Grid of images. I am not sure if using a grid is the correct choice. Here is a mockup image of what I want it to look like:

mockup

The red box represents the ScrollViewer. Inside it, is some type of layout container (Grid at the moment) that has two rows of images (green squares) but a dynamic amount of columns that can change at runtime, that can be scrolled to. Another condition is that I want to resize them so that 6 images (and only 6!) are always visible.

So in XAML:

    <ScrollViewer Name="scrollViewer1">
        <Grid Name="grid1"></Grid>
    </ScrollViewer>

Then using C# I think I need to dynamically add columns. Then listening to scrollViewer1's SizeChanged event I need to dynamically calculate the size of the rows and columns so that 3 images are always in view. For example:

ColumnDefinition gridColN = new ColumnDefinition();
grid1.ColumnDefinitions.Add(gridColN);

Problem #1: Dynamically adding more columns makes the grid cells keep getting smaller and smaller and never scroll within the ScrollViewer until there are 10+ columns.

Expected result: The end result should be a horizontal stream of images, 6 visible at a time, that will resize when the outter container or window is resized. I am trying to size their width dynamically, but setting them to 1/3 of the containers width does not work.

Questions: Is this the correct approach? Should I use Grid inside the ScrollViewer? Do I have to manually calculate the sizes or is there a way to let them fill the container?

Upvotes: 2

Views: 1494

Answers (1)

dtesenair
dtesenair

Reputation: 706

Grid width should be calculated as

grid1.Width = (scrollViewer1.ViewportWidth / 3) * grid1.ColumnDefinitions.Count;
grid1.Height = (scrollViewer1.ViewportHeight / 2) * grid1.RowDefinitions.Count;

This seemed to work for me:

XAML:

<DockPanel>
   <ListBox Width="150" DockPanel.Dock="Left" BorderBrush="AliceBlue" BorderThickness="2">
      <Button Name="AddColumn_Button" Width="100" Height="25" Content="Add Column" Click="AddColumn_Button_Click" Margin="5"/>
      <Button Name="AddRow_Button" Width="100" Height="25" Content="Add Row"  Margin="5" Click="AddRow_Button_Click" />
   </ListBox>
   <ScrollViewer Name="scrollViewer1" BorderBrush="AliceBlue" BorderThickness="2" SizeChanged="scrollViewer1_SizeChanged" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Margin="1">
        <Grid Name="grid1" ShowGridLines="True" >
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
        </Grid>
    </ScrollViewer>
</DockPanel>

CODE BEHIND:

    private void scrollViewer1_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        SizeGrid();
    }

    private void AddColumn_Button_Click(object sender, RoutedEventArgs e)
    {
        ColumnDefinition gridColN = new ColumnDefinition();
        grid1.ColumnDefinitions.Add(gridColN);
        SizeGrid();
    }

    private void AddRow_Button_Click(object sender, RoutedEventArgs e)
    {
        RowDefinition row = new RowDefinition();
        grid1.RowDefinitions.Add(row);
        SizeGrid();
    }

    private void SizeGrid()
    {
        grid1.Width = (scrollViewer1.ViewportWidth / 3) * grid1.ColumnDefinitions.Count;
        grid1.Height = (scrollViewer1.ViewportHeight / 2) * grid1.RowDefinitions.Count;        
    }

Upvotes: 2

Related Questions