locked
GridView only adding new columns, not new rows RRS feed

  • Question

  • I have a simple GridView that is bound to an ObservableCollection. I have two, possibly related, problems:

    1. On initial load the ObservableCollection is empty (but not null). After the page has loaded, a web service call retrieves a number of items, which are added in a foreach loop to the ObservableCollection. After this, the GridView has only one column, and with one row for each of the items in the ItemsSource. Note that I have not actively configured the GridView in any way to have a specific number of rows or columns. The desired effect is for the items to be placed in a number of rows and columns to best fit the screen.
    2. When I add extra items to the ObservableCollection , new columns are added, but never new rows. When many items have been added this makes the GridView very wide, but not very tall.

    The GridView is placed inside a ViewBox, which just means that the GridView will be scaled down as more items are added.

    An example:

    Let's assume the web service call get's two items, that are added to the ObservableCollection. Then the GridView renders two rows and one column. The best fit to the screen would have been one row and two columns. After a while fourteen extra items have been added to the ObservableCollection. The GridView now contains two rows (as before), and eight columns. The best fit here would have been four rows and four columns, or perhaps three rows and six columns. As more items are added the GridView column count increases even further, but the row count stays at the initial number.

    I am hoping that all I need to do is set some property on the GridView, or perhaps call some GridView invalidate-method on the CollectionChanged event of the ObservableCollection.

    The GridView is defined as follows:

    <Viewbox Stretch="Uniform">
    <GridView ItemsSource="{Binding Achievements}">
    <GridView.ItemTemplate>
    <DataTemplate>
    <Button Style="{StaticResource AppBarButtonStyle}" Content="{Binding Title}" FontSize="8"/>
    </DataTemplate>
    </GridView.ItemTemplate>
    </GridView>
    </Viewbox>

    Saturday, October 12, 2013 11:57 AM

Answers

  • You cannot directly control the GridView's row and columns. It will figure that out based on the size and number of its items and will fill horizontally before vertically. It sounds like since you've given the GridView infinite width in the ViewBox it never needs to wrap to fit on the screen, and so it doesn't. You'll need to add some sizing logic to keep the width more reasonable. If you want to shrink on a ViewBox as it fills watch height and width and lock down the aspect ratio, but be careful you cant get so many items they shrink to where they cant be read or touched. Allowing scrolling and semantic zoom may provide a more usable experience than the ViewBox

    --Rob

    Saturday, October 12, 2013 2:25 PM
    Moderator

All replies

  • You cannot directly control the GridView's row and columns. It will figure that out based on the size and number of its items and will fill horizontally before vertically. It sounds like since you've given the GridView infinite width in the ViewBox it never needs to wrap to fit on the screen, and so it doesn't. You'll need to add some sizing logic to keep the width more reasonable. If you want to shrink on a ViewBox as it fills watch height and width and lock down the aspect ratio, but be careful you cant get so many items they shrink to where they cant be read or touched. Allowing scrolling and semantic zoom may provide a more usable experience than the ViewBox

    --Rob

    Saturday, October 12, 2013 2:25 PM
    Moderator
  • i would remove the viewbox and would do it by sertting the itemheight and itemwidth.

    in xaml:

    <GridView.ItemsPanel>
                    <ItemsPanelTemplate>
                        <ItemsWrapGrid GroupPadding="0,0,70,0" SizeChanged="ItemsWrapGrid_SizeChanged" />
                    </ItemsPanelTemplate>
                </GridView.ItemsPanel>

    and in code:

    private void ItemsWrapGrid_SizeChanged(object sender, SizeChangedEventArgs e)
            {
                var itemHeight = e.NewSize.Height / numberofItems;
                ((ItemsWrapGrid)sender).ItemHeight = itemHeight;
            }


    Microsoft Certified Solutions Developer - Windows Store Apps Using C#

    Saturday, October 12, 2013 2:29 PM
  • Unfortunately in this case scrolling and sematic zoom are not an option. The items in the GridView are in fact filling out the background, and are in the first iteration rendered as buttons just to get the rigth look. The DataTemplate will in due time be modified to be an image and textblock instead.

    But thank you for the 'infinite width' pointe. This answers my issue 2, but doesn't explain issue 1, where the initial items are all rendered in a single column, thereby defining the (permanent) number of rows in the GridView.

    Saturday, October 12, 2013 6:39 PM