Using DataTemplateSelector in Metro Style App

This is a short post on using DataTemplateSelector to show items differently in the same list.

Lets say we have

public class Customer
{
public string Id { get; set; }
public string Name { get; set; }
}

public class PreferredCustomer: Customer
{
public int Discount { get; set; }
}

and we create a list of customers like this and set the itemssource to any ItemsControl

List<customers> = new List();
customers.Add(new Customer { Id = “1”, Name = “customer..1” });
customers.Add(new PreferredCustomer { Id = “2”, Name = “customer..2”, Discount=10 });
customers.Add(new Customer { Id = “3”, Name = “customer..3” });
customers.Add(new PreferredCustomer { Id = “4”, Name = “customer..4”, Discount=20 });
customers.Add(new Customer { Id = “5”, Name = “customer..5″ });

list1.ItemsSource = customers;

In resources section, we create couple of datatemplates and a DataTemplateSelector which returns a datatemplate based on the item.

We bind the ItemTemplateSelector property of Listview to the one we created in resource section.

public class CustomerDataTemplateSelector : DataTemplateSelector
{
public DataTemplate CustTemplate { get; set; }
public DataTemplate PrefCustTemplate { get; set; }

protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
Customer c = (Customer)item;
DataTemplate dt = c is PreferredCustomer ? this.PrefCustTemplate : this.CustTemplate;
return dt;
}

}

<Page
x:Class=”Application1.BlankPage1″
xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation&#8221;
xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml&#8221;
xmlns:local=”using:Application1″
xmlns:d=”http://schemas.microsoft.com/expression/blend/2008&#8243;
xmlns:mc=”http://schemas.openxmlformats.org/markup-compatibility/2006&#8243;
mc:Ignorable=”d”>
<Page.Resources>
<DataTemplate x:Key=”dtCustomer”>
<TextBlock Text=”{Binding Name}” FontSize=”25″/>
</DataTemplate>
<DataTemplate x:Key=”dtPrefCustomer”>
<TextBlock Foreground=”Green” Text=”{Binding Name}” FontSize=”25″ FontWeight=”Bold”/>
</DataTemplate>
<local:CustomerDataTemplateSelector x:Key=”cdst” CustTemplate=”{StaticResource dtCustomer}” PrefCustTemplate=”{StaticResource dtPrefCustomer}”/>
</Page.Resources>
<Grid Background=”{StaticResource ApplicationPageBackgroundBrush}”>

<ListView Width=”300″ x:Name=”list1″ FontSize=”30″ ItemTemplateSelector=”{StaticResource cdst}”/>

</Grid>
</Page>

Here is the result.

Customizing GridView Items in Metro App

This is a short post on customizing height and width of the items in GridView. by default if we use a WrapGrid we get items as bunch of tiles.

We can change the height and width of the tiles by deriving from gridview and overriding PrepareContainerForItemOverride method like below. In the code I am making the tile double the width if the city is “City 4”.  Ofcourse we can add properties and not hardcode stuff like shown
public class MyGridView : GridView
{
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
var obj = item as Person;
var gi = element as GridViewItem;
if (obj.City == “City 4”)
{
gi.SetValue(VariableSizedWrapGrid.ColumnSpanProperty, 2);
gi.Background = new SolidColorBrush(Colors.Beige);
gi.Foreground = new SolidColorBrush(Colors.Black);
gi.FontSize = 22;
}
base.PrepareContainerForItemOverride(gi, item);
}
}

Here is the xaml and code I used in the BlankPage .

protected override void OnNavigatedTo(NavigationEventArgs e)
{
Random r = new Random();
var items = Enumerable.Range(0, 50).Select(x =>
new Person { Id = x,
Name = “person..” + x.ToString(),
City = “City ” + (r.Next(0,5)).ToString() });
cvs.Source = items;

}

<Page.Resources>         <CollectionViewSource x:Name=”cvs”/>     </Page.Resources>

<local:MyGridView FontSize=”20″ FontFamily=”segoe ui” Margin=”100″ ItemsSource=”{Binding Source={StaticResource cvs}}” >
<GridView.ItemTemplate>
<DataTemplate>
<StackPanel HorizontalAlignment=”Left” >
<TextBlock Text=”{Binding Id}” />
<TextBlock Text=”{Binding Name}” />
<TextBlock Text=”{Binding City}” />
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>

<GridView.ItemsPanel>
<ItemsPanelTemplate>
<VariableSizedWrapGrid ItemHeight=”120″ ItemWidth=”120″ MaximumRowsOrColumns=”6″ Orientation=”Vertical”/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>

</local:MyGridView>

Here is the result.