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: