Out of the two above I would say GridView. Since you need to support so many different screen sizes and ratios you shouldn't have fixed sizes.
As the guidelines states: Guidelines for window sizes and scaling to screens(Windows Store apps)
Design apps that look good at any width, and you automatically get
support for different screen sizes and orientations. Plan your app for
resizing from full screen down to the minimum width so that the UI
reflows gracefully for various screen sizes, window sizes, and
orientations.
Since you also need to cater for the snapped mode (which you can't choose not to have in you application) having buttons will add even more manual work which means a lot of hard to maintain UI code. If you use a gridview you can pair it up with a listview for the snapped mode (gridview for full mode, listview for snapped) as in the templates.
You can certainly restrict the sizes in a GridView without it require even a fifth of the work needed for buttons, so I'm not quite sure what you mean by "No guarantees of item size".
Anyway, as the guidelines says, buttons should NOT be used for navigation to a page. These are just guidelines, but I reckon they make sense.
Here are: Guidelines and checklist for buttons (Windows Store apps)
Don't use a button when the action is to navigate to another page; use
a link instead. Exception: For wizard navigation, use buttons labeled
"Back" and "Next".
I would use GriView and combine it with a semantic zoom if appropriate.
Example with GridView and ItemsControl, here is the result:
Code for the UI (View):
<Page
x:Class="App1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<GridView x:Name="gridView">
<GridView.ItemTemplate>
<DataTemplate>
<Border Width="150" Height="150" BorderBrush="Pink" BorderThickness="10" Background="Aqua">
<TextBlock Foreground="Black" FontSize="20" Text="{Binding}"/>
</Border>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
<ItemsControl Grid.Row="1" x:Name="itemscontrol">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Width="150" Height="150" BorderBrush="Yellow" BorderThickness="10" Background="LightGreen">
<TextBlock Foreground="Black" FontSize="20" Text="{Binding}"/>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
</Page>
Code for the codebehind (the .cs file that belongs to the XAML):
using System.Collections.Generic;
namespace App1
{
public sealed partial class MainPage
{
public MainPage()
{
InitializeComponent();
DataContext = this;
var items = new List<string> { "Iris", "Paul", "Ben", "Cate", "Daniel", "Ryan", "Iris 2", "Paul 2", "Ben 2", "Cate 2", "Daniel 2", "Ryan 2" };
gridView.ItemsSource = items;
itemscontrol.ItemsSource = items;
}
}
}
The result at a higher resolution, notice that the items keep their fixed size and don't scale to fit the screen.
Stretching the items height over one row with the GridView:
<GridView x:Name="gridView">
<GridView.ItemTemplate>
<DataTemplate>
<Border Width="150" BorderBrush="Pink" BorderThickness="10" Background="Aqua">
<TextBlock Foreground="Black" FontSize="20" Text="{Binding}"/>
</Border>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.ItemContainerStyle>
<Style TargetType="GridViewItem">
<Setter Property="VerticalContentAlignment" Value="Stretch" />
</Style>
</GridView.ItemContainerStyle>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
By the way, GridView inherits from the ItemsControl if you didn't know.