Mark
Mark

Reputation: 863

GridView with item width adjusted automatically

I have a grid view with item source xbind to an observable collection. The collection consists of user control (which essentially is a button). I want the grid view to accommodate the items in the following way.

1) If it can show two items in one row go ahead.

2) If it can only display one item, it needs to stretch it to occupy all the space.

If point 2 is not followed, there is only one item in a row as the second item cannot come into the first row there is all this empty space which looks really bad.

<GridView ItemsPanel="{StaticResource VariableSizedItemTemplate}" ItemContainerStyleSelector="{StaticResource VariableSizedStyleSelector}" Name="ContentGrid" ItemsSource="{x:Bind projectsButtonCollection,Mode=OneWay}"></GridView>

 <ItemsPanelTemplate x:Key="VariableSizedItemTemplate">
   <VariableSizedWrapGrid Orientation="Horizontal"/>
 </ItemsPanelTemplate>

VariableSizedStyle selector is currently assigning styles according to a property of the user control.Property is just an int which we initialize when creating the user control. Styles have Row and col spans.

 <Setter Property="VariableSizedWrapGrid.RowSpan"
           Value="2" />
 <Setter Property="VariableSizedWrapGrid.ColumnSpan"
           Value="2" />

I don't think the current code will help as I want to change the way what I am doing it right now, Items are adjusted beautifully till there is space for only one user control per row. Then I have all this left space.

Upvotes: 0

Views: 298

Answers (1)

AbsoluteSith
AbsoluteSith

Reputation: 1967

One way to achieve what you are trying to do is by getting the trigger on GridView_SizeChanged event and based on the size of the window you can have 1,2,3,4 items etc whichever is convenient. In this code I've done something similar in the below code

private async void GridView_SizeChanged(object sender, SizeChangedEventArgs e)
{
    try
    {
        ItemsWrapGrid itemsWPGrid = (ItemsWrapGrid)((GridView)sender).ItemsPanelRoot;
        double viewWidth = ApplicationView.GetForCurrentView().VisibleBounds.Width;
        int number = 2;
        //here 200 is the size if the item and number is the number of items in a row
        number = Convert.ToInt32(Math.Floor(viewWidth / 200));
        Debug.WriteLine("The current height is " + itemsWPGrid.ItemHeight + " and width " + itemsWPGrid.ItemWidth + "and view width " + viewWidth);
        {
            await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
               () =>
               {
                    //Set the width of the items based on how many number of items that can fit
                   if (viewWidth < 350)
                   {
                       //Display 2 items in a row and the 45 is used for margin/padding
                       itemsWPGrid.ItemWidth = (viewWidth - 45) / 2;
                   }
                   else if (number >= 4 && viewWidth >= 500)
                   {
                       itemsWPGrid.ItemWidth = (viewWidth - 100) / (number - 1);
                   }
                   else if (number == 3 && viewWidth < 400)
                   {
                       if (viewWidth < 375)
                           itemsWPGrid.ItemWidth = (viewWidth - 10) / number;
                       else
                           itemsWPGrid.ItemWidth = (viewWidth - 30) / number;
                   }
                   else if (number == 3 && viewWidth > 400)
                   {
                       itemsWPGrid.ItemWidth = (viewWidth - 50) / number;
                   }


                   //Below takes care of the condition to make sure the aspect ratio is corrected.
                   if (!double.IsNaN(itemsWPGrid.ItemWidth) && viewWidth > 350)
                       itemsWPGrid.ItemHeight = itemsWPGrid.ItemWidth * 1.7;
                   else if (viewWidth == 360 && double.IsNaN(itemsWPGrid.ItemWidth))
                   {
                       itemsWPGrid.ItemHeight = viewWidth / 3 * 1.7;
                   }
                   else if (!double.IsNaN(itemsWPGrid.ItemWidth))
                   {
                       itemsWPGrid.ItemHeight = itemsWPGrid.ItemWidth * 1.5;
                   }
               });
        }
        Debug.WriteLine("The new height is " + itemsWPGrid.ItemHeight + " and width " + itemsWPGrid.ItemWidth + "and view width " + viewWidth);
    }
    catch
    {

    }
}

Upvotes: 1

Related Questions