1

I would like to fill the space available in the GridView control with images. In specific, I would like to make 4 columns, each column with an Image. No space between columns.

First thought: GridView fills the whole space available in the page, so I just need a converter that binds to the ActualWidth property of the GridView and than divide it by four (columns). This should give me four columns with the same Width. The problem is that unfortunatly Width is not a simple number and dividing by 4 it gives probably a not perfect number, so the sum of the 4 columns Width can go over the grid and the result is that I can see only three columns instead of four. Even if I set the margin and the padding to zero, the result does'nt change. The code is the following:

<GridView x:Name="Photos">
        <GridView.ItemTemplate>
            <DataTemplate>
                <Image Source="{Binding Url}" 
                       Width="{Binding ElementName=Photos, Path=ActualWidth, Converter={StaticResource DivideByFourConverter}}"
                       Height="{Binding ElementName=Photos, Path=ActualWidth, Converter={StaticResource DivideByFourConverter}}
                       Stretch="UniformToFill" />
            </DataTemplate>
        </GridView.ItemTemplate>
    </GridView>

Second thought: try to not set the Width and Height on the Image, but make a WrapGrid setting the maximum number of rows and columns. Nothing, I see the same result....

<GridView x:Name="Photos">
        <GridView.ItemsPanel>
            <ItemsPanelTemplate>
                <ItemsWrapGrid MaximumRowsOrColumns="4"
                               Orientation="Horizontal" />
            </ItemsPanelTemplate>
        </GridView.ItemsPanel>
        <GridView.ItemTemplate>
            <DataTemplate>
                <Image Source="{Binding Url}" 
                       Stretch="UniformToFill" />
            </DataTemplate>
        </GridView.ItemTemplate>
    </GridView>

Just to be clear, here is the screen: https://i.stack.imgur.com/SL7QP.png

Isn't it possible to have a simple grid with items filling it without margins? The Platform is Windows Phone 8.1 RT so no possibility of using GridViewColumns.

I was even thinking of doing a hidden Grid with 4 columns with * sizing and binding the Image to the Width of a column but... I was searching for a smarter solution :)

xTuMiOx
  • 433
  • 5
  • 18
  • Have you tried increasing the margin of the GridView slightly a few pixels? Something like `Margin="0,0,-4,0"`. I don't know if it'll work, give it a try. – Decade Moon Nov 29 '14 at 10:52
  • This can work, but it differs from size to size. Ex.: WVGA screen is not a 720p screen where we can set more margin – xTuMiOx Nov 29 '14 at 16:10

1 Answers1

4

You shouldn't bind to the ActualWidth property. The docs mention:

For purposes of ElementName binding, ActualWidth does not post updates when it changes (due to its asynchronous and run-time calculated nature). Do not attempt to use ActualWidth as a binding source for an ElementName binding. If you have a scenario that requires updates based on ActualWidth, use a SizeChanged handler.

I managed to get it to work like this:

<GridView x:Name="GridView" SizeChanged="GridView_SizeChanged">
    <GridView.ItemsPanel>
        <ItemsPanelTemplate>
            <ItemsWrapGrid
                MaximumRowsOrColumns="4"
                Orientation="Horizontal" />
        </ItemsPanelTemplate>
    </GridView.ItemsPanel>
    <GridView.ItemTemplate>
        <DataTemplate>
            <Image Source="ms-appx:///Assets/Logo.png" />
        </DataTemplate>
    </GridView.ItemTemplate>

    <x:String>Test</x:String>
    <x:String>Test</x:String>
    <x:String>Test</x:String>
    <x:String>Test</x:String>
    <x:String>Test</x:String>
    <x:String>Test</x:String>
    <x:String>Test</x:String>
    <x:String>Test</x:String>
    <x:String>Test</x:String>
    <x:String>Test</x:String>
    <x:String>Test</x:String>
    <x:String>Test</x:String>
</GridView>

And then in the code behind:

private void GridView_SizeChanged(object sender, SizeChangedEventArgs e)
{
    var panel = (ItemsWrapGrid)GridView.ItemsPanelRoot;
    panel.ItemWidth = panel.ItemHeight = e.NewSize.Width / 4;
}

Screenshot

It works with the 6" emulator too.

Decade Moon
  • 32,968
  • 8
  • 81
  • 101