0

I have a grid of 12 non clickable buttons(they are just indicators) in the center of my page in the following manner.

enter image description here

There is going to be more stuff around this grid and I need the items to be at their exact place and of the same width and height. I am confused whether to use a grid with (star sized) rows and columns with buttons in them or a gridview with a wrap panel with MaxRowsAndColumns set to 3 and Orientation set to Horizontal. Here are my arguments for and against each of the approaches:-

Buttons:-

Pros:-

  • Fixed position and height and width guaranteed.
  • Adaptable to all screen sizes
  • Easy to code

Cons:-

  • Will have to write a very large XAML and C# code because I will not be able to use Data Template here and will have to define lots of variables and grids and set values of each textblock separately.

GridView

Pros:-

  • DataTemplate available so easy to set values via ObservableCollection
  • Smaller code than the one created using buttons

Cons:-

  • No guarantees of item size. Will have to hard code it in XAML or Bind it to properties in Model and then calculate the value inside XAML.

Please let me know which one is the better alternative. Is there any other easier way to do it apart from the methods mentioned above?

Thanks, Rajeev

Rajeev Bhatia
  • 2,974
  • 1
  • 21
  • 29

2 Answers2

3

Use ItemsControl, it offers DataTemplate as well as item size.

Farhan Ghumra
  • 15,180
  • 6
  • 50
  • 115
2

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:

GridView at the top, ItemsControl at the bottom. Notice that they are in a Grid that has two rows and no columns

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.

enter image description here

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.

Iris Classon
  • 5,752
  • 3
  • 33
  • 52
  • Thanks Iris. My app is not going to support Snapped View. It is not going to be uploaded to the store and will be deployed on the client devices. I was going to use buttons with Grid as the content since the buttons will be clickable on another page and I might be able to reuse the same code. Can you dynamically(in C#) set the size of the GridView items without binding it to a property in your model? – Rajeev Bhatia Sep 03 '13 at 07:30
  • I believe you can, although i've never done that since I always use MVVM. For the items themselves you can set a fixed size on the datatemplate. Give me a minute and I'll whip up an example for you. – Iris Classon Sep 03 '13 at 07:32
  • I do not use MVVM and I see the Windows 8 app code always doing it by switching data templates with fixed sized items(while snapping etc.). Thanks again Iris! – Rajeev Bhatia Sep 03 '13 at 07:35
  • Thanks for the example Iris. I see that you have set the height and width of the control in the DataTemplate to 150 in XAML. I think I would need to calculate this in my c# code since I would not know the full screen size and thus smaller dimensions would give more than 3 items per row and less rows while larger dimensions would give me less than 3 items per row and more rows than I need. After I calculate the exact item size needed in C#, how would I set it as the size of the item inside the DataTemplate in the GridView/ItemsControl? – Rajeev Bhatia Sep 03 '13 at 08:49
  • 1
    Try here: http://stackoverflow.com/questions/14905907/size-gridviewitems-to-fill-gridview As for code here: http://code.msdn.microsoft.com/windowsapps/How-to-create-a-GridView-d3129308 – Iris Classon Sep 03 '13 at 09:00
  • That Code Sample looks like it will do the trick...thanks again Iris! – Rajeev Bhatia Sep 03 '13 at 09:49
  • 1
    NP, glad you got it sorted! – Iris Classon Sep 03 '13 at 12:43