Jens Willmer

Tutorials, projects, dissertations and more..

How to display different Items in a GridView

The last weeks I was coding an app for the windows 8 store and this weekend I try to complete the first version and send it to the app store. One problem that I had while I was coding was that I wanted to display different Items in a GridView. I came up with the following solution to accomplish this and it worked that well that I thought some readers could be interested in it ;-)

In my example I use the Model-view-controller (MVC) architecture with a little help from the MVVM-Light Toolkit.

First create some models you’d like to display:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    //...
}
public class Car
{
    public string Model { get; set; }
    public double Price { get; set; }
    //...
}

Second you add the models to a collection which you’d like to data bind against:

public class MainViewModel : ViewModelBase
{
    private ObservableCollection<object> _gridViewSource;
    public ObservableCollection<object> GridViewSource
    {
        get { return _gridViewSource; }
        set
        {
            _gridViewSource = value; 
            RaisePropertyChanged("GridViewSource");
        }
    }

    public MainViewModel()
    {
        var person = new Person() {FirstName = "Jens", LastName = "Willmer"};
        var car = new Car() {Model = "BMW-xyz", Price = 15.000};

        GridViewSource = new ObservableCollection<object>();
        GridViewSource.Add(person);
        GridViewSource.Add(car);
    }
}

After this you create for each Model a custom UserControl, for testing I added two controls with different background colors in the XAML:

<UserControl
    x:Class="App.PersonItemControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid Background="Red"  Width="20" Height="20"/>
</UserControl>

<UserControl
    x:Class="App.CarItemControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid Background="Green"  Width="20" Height="20"/>
</UserControl>

Then you add an IValueConverter that does the switching between the different Controls:

public class ContentTypeToControlConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        if (value != null)
        {
            if (value is Person)
            {
                return new PersonItemControl();
            }
            else if (value is Car)
            {
                return new CarItemControl();
            }
        }

        return null;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

Now for the last step you only have to create a GridView in your main XAML and add the source with a converter like this:

<Page
    x:Class="App.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App">
    <Grid>
        <GridView ItemsSource="{Binding GridViewSource}">
            <GridView.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <ContentControl Content="{Binding Converter={StaticResource local:ContentTypeToControlConverter}}" />
                    </Grid>
                </DataTemplate>
            </GridView.ItemTemplate>
        </GridView>
    </Grid>
</Page>

As result of my example code you will get this:

result