Reputation: 863
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
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