DataTemplate In XAML (WPF, Windows Phone, Windows 8 and Silverlight)

Introduction

XAML is a markup language that is currently very popular. We develop applications on all platforms, Windows, web and mobile or Tablets. Every platform control, action or behavior is nearly the same. Also supported are 2d, 3d and so many features. When designing XAML I consider customizing the controls, in other words a developer can customize a control based on his business or user requirements. It's very flexible and comfortable. Obviously this concept comes from Windows application custom controls and web applications, before WPF or XAML we also customized our controls but not a flexibly as with WPF or XAML because we did not use any markup for customization. Instead customization was based on our code, here you can customize a control of any shape and easily use it. It’s very simple and sweeter.

In this article I‘ll try to explain DataTemplates in XAML (WPF, Windows Phone, Silverlight or Windows 8) with some cool examples.

ComboBox with country

The preceding is an image of a simple ComboBox with country. It’s very good and simple for understanding from the user point of view but think of doing it with a normal Windows Form, it’s a bit complicated and you‘ll have a horrible experience, at least that is my personal experience.

user point of view

And the same thoughts result from doing it with XAML. It’s just a few hours task, anybody can easily do it like this.



My target shows how different it is for a normal Windows Forms application and an XAML application. In short, before WPF or after WPF. After XAML our control becomes more powerful, simple and flexible. The Datatemplate displays a collection of data, the preceding was a simple Combobox example of a datatemplate.

What a DataTemplate is

A DataTemplate helps us to display a Collection of data in a customized format or based on business requirements. In simpler terms, a DataTemplate provides you great flexibility to define the presentation of your data on the user interface.

For example, one common use of binding is to display data in a list. For example a combobox or listbox. Whether retrieving data from a database or using some static or list and collection of data, it’s useful to the display. The data is shown one item at a time. As I already explained above, in the combobox country with respective country image, here the binding of two items. You can easily do this using XAML tools with the DataTemplate Concept.

I will do that above example step-by-step.

In the preceding sample, I am binding a list of countries in a Combobox with respective country images. For that I am using an Entity class for store country information with respective Country picture.

  1. public class Entity  
  2.     {  
  3.         public string country { getset; }  
  4.         public string Image { getset; }  
  5.     public static ObservableCollection<Entity> ListOfCountry()  
  6.     {  
  7.         string ImageUrl = AppDomain.CurrentDomain.BaseDirectory + "Images\\Countries\\";  
  8.    
  9.         ObservableCollection<Entity> country = new ObservableCollection<Entity>()  
  10.         {  
  11.    
  12.               new Entity{ country="Afghanistan", Image=ImageUrl+"AF.png"},  
  13.               new Entity{ country="Albania" ,Image=ImageUrl+"AL.png" },  
  14.               new Entity{ country="Algeria" ,Image=ImageUrl+"DZ.png" },  
  15.               new Entity{ country="American Samoa" ,Image=ImageUrl+"AS.png" },  
  16.               new Entity{ country="Andorra" ,Image=ImageUrl+"AD.png" },  
  17.               new Entity{ country="Angola" ,Image=ImageUrl+"AO.png" },  
  18.               new Entity{ country="Anguilla" ,Image=ImageUrl+"AI.png"},  
  19.               new Entity{ country="Antarctica" ,Image=ImageUrl+"AQ.png"},               
  20.               new Entity{ country="Argentina" ,Image=ImageUrl+"AR.png" },  
  21.               new Entity{ country="Belgium" ,Image=ImageUrl+"BE.png" },  
  22.               new Entity{ country="Belize" ,Image=ImageUrl+"BZ.png" },  
  23.               new Entity{ country="Benin" ,Image=ImageUrl+"BJ.png" },  
  24.               new Entity{ country="Bermuda" ,Image=ImageUrl+"BM.png"},  
  25.               new Entity{ country="Bhutan" ,Image=ImageUrl+"BT.png" },  
  26.               new Entity{ country="Bolivia" ,Image=ImageUrl+"BO.png"},  
  27.               new Entity{ country="Botswana" ,Image=ImageUrl+"BW.png" },   
  28.               new Entity{ country="Brazil" ,Image=ImageUrl+"BR.png"  },  
  29.               new Entity{ country="Hong Kong" ,Image=ImageUrl+"HK.png" },  
  30.               new Entity{ country="Hungary" ,Image=ImageUrl+"HU.png" },  
  31.               new Entity{ country="Iceland" ,Image=ImageUrl+"IS.png" },  
  32.               new Entity{ country="India" ,Image=ImageUrl+"IN.png" },  
  33.               new Entity{ country="Indonesia" ,Image=ImageUrl+"ID.png"},   
  34.               new Entity{ country="Iran" ,Image=ImageUrl+"IR.png" },  
  35.               new Entity{ country="Iraq" ,Image=ImageUrl+"IQ.png" },  
  36.               new Entity{ country="Ireland" ,Image=ImageUrl+"IE.png"},   
  37.               new Entity{ country="Israel" ,Image=ImageUrl+"IL.png" },  
  38.               new Entity{ country="Italy" ,Image=ImageUrl+"IT.png" }  
  39.         };  
  40.         return country;  
  41.     }  

In the page load event I am loading country data because it’s a small sample. That’s why I did not create a separate view model but in the code behind I define one collection, the ListOfCountry list. This will store all country information with respective images. Here is also the assigning of the datacontext for the view, like this:
 

  1. public partial class MainWindow : Window  
  2.    {  
  3.        public MainWindow()  
  4.        {  
  5.            InitializeComponent();  
  6.            _CountryEntity = Entity.ListOfCountry();  
  7.            this.DataContext = this;  
  8.        }  
  9.        public ObservableCollection<Entity> _CountryEntity;  
  10.        public ObservableCollection<Entity> ListofCountry  
  11.        {  
  12.            get  
  13.            {  
  14.                return _CountryEntity;  
  15.            }  
  16.            set  
  17.            {  
  18.                _CountryEntity = value;  
  19.   
  20.            }  
  21.        }  
  22.    }     

 

In the view I define one simple XAML control.

 

  1. <ComboBox Name="CountryCombo"   
  2.     ItemsSource="{Binding ListofCountry}"  Margin="42,13.895,55,29" Grid.Row="1" >  
  3.             <ComboBox.ItemTemplate>  
  4.                 <DataTemplate>  
  5.                     <StackPanel Orientation="Horizontal">  
  6.                         <Image Width="20" Height="20" Margin="5" Source="{Binding Image}"/>  
  7.                         <TextBlock Margin="5" Text="{Binding country}"/>  
  8.                     </StackPanel>  
  9.                 </DataTemplate>  
  10.             </ComboBox.ItemTemplate>  
  11.         </ComboBox>  

In the preceding I am binding a combobox. For that define an ItemSource, this ‘ll indicate the source of the data or this will indicate the data link for the respective control.

Then by defining the items template the visual structure of the Combobox data is defined. Since our target shows the image with country name, for that I use one stack panel
 and I set the orientation to horizontal. In an inside stack panel I use an image first then textblock for display the Country name horizontally .

DataTemplate Sample In XAML(Windows 8, Silverlight, WPF and Windows Phone) 

After the preceding small sample I will show some more demos here. My idea is to cover the datatemplate concept end to end in XAML. For that the following shows 

a demo on Windows 8, Silverlight, Windows Phone and WPF. My input wil be the same for every demo.

In the screen above I show a data template as C# Corner Top Member. For this I am using the MVVM model for storing member data and view-model for fetching the data from the model but I did not create an extra model and view Model class. For this, because here I want to focus only on the data template.

I place both logic, the Model and View - Model classes here only in the code behind and load event load my model data.

  1. public class Authors  
  2.     {         
  3.         public string Name { getset; }  
  4.        
  5.         public string Point { getset; }  
  6.          
  7.         public string Country { getset; }  
  8.    
  9.         public string Image { getset; }  
  10.    
  11.         public string Ranks { getset; }  
  12.         public static ObservableCollection<Authors> GetAuthorsRecord()  
  13.         {  
  14.             ObservableCollection<Authors> AuthorsRecords = new ObservableCollection<Authors>  
  15.            {  
  16.                new Authors{Point="40960",Name="Mahesh Chand",Country="Philadelphia, United States",Image="Image/mahesh.png",Ranks="1"},  
  17.                new Authors{Point="18063",Name="Vulpes",Country="United Kingdom",Image="Image/b942f9.gif",Ranks="2"},  
  18.                new Authors{Point="12215",Name="Dinesh Beniwal",Country="India",Image="Image/dbeniwal321.jpg",Ranks="3"},  
  19.                new Authors{Point="11372",Name="Rohatash Kumar",Country="India",Image="Image/rohatash.jpg",Ranks="4"},  
  20.                new Authors{Point="11088",Name="Dhananjay Kumar",Country="India",Image="Image/dhananjaycoder.png",Ranks="5"},  
  21.                new Authors{Point="10964",Name="Satyapriya Nayak",Country="Bhubaneswar, India",Image="Image/satyapriyanayak.jpg",Ranks="6"},  
  22.                new Authors{Point="10850",Name="Vijai Anand",Country="New Jersey, United States",Image="Image/anavijai.png",Ranks="7"},  
  23.                new Authors{Point="10391",Name="Abhimanyu K Vatsa",Country="Bokaro Steel City, India",Image="Image/abhikumarvatsa.jpg",Ranks="8"},  
  24.                new Authors{Point="8761",Name="Sam Hobbs",Country="Granada Hills, United States",Image="Image/SamTomato.jpg",Ranks="9"},  
  25.                new Authors{Point="8512",Name="Suthish Nair",Country="India",Image="Image/suthish_nair.jpg",Ranks="10"},  
  26.                 
  27.            };  
  28.             return AuthorsRecords;  
  29.         }  
  30.     }  
  31.    
  32. In this list I am storing above data and binding this data on view as ItemSource.   
  33. public ObservableCollection<Authors> _Authorsr;  
  34.         public ObservableCollection<Authors> ListofAuthors  
  35.         {  
  36.             get  
  37.             {  
  38.                 return _Authors;  
  39.             }  
  40.             set  
  41.             {    
  42.                 _Authors = value;  
  43.                                     
  44.             }  
  45.         }    
View
  1. <ListBox.ItemTemplate>  
  2.               <DataTemplate>  
  3.                   <StackPanel Orientation="Horizontal">  
  4.                       <Grid Margin="0,5,0,0">  
  5.                           <Grid.ColumnDefinitions>  
  6.                               <ColumnDefinition Width="auto"></ColumnDefinition>  
  7.                               <ColumnDefinition></ColumnDefinition>  
  8.                           </Grid.ColumnDefinitions>  
  9.                           <Image Source="{Binding Image}" Height="80" Width="80" Grid.Column="0"></Image>  
  10.                           <StackPanel Grid.Column="1" Orientation="Vertical" Width="150" Height="100" >  
  11.                               <TextBlock Text="{Binding Name}" Margin="5,1,0,1"></TextBlock>  
  12.                               <TextBlock Text="{Binding Country}" Margin="5,1,0,1"></TextBlock>  
  13.                               <StackPanel Orientation="Horizontal">  
  14.                                   <TextBlock Text="Ranks #" Margin="5,1,0,1"></TextBlock>  
  15.                                   <TextBlock Text="{Binding Ranks}" Margin="3,1,0,1"></TextBlock>  
  16.                               </StackPanel>  
  17.                               <StackPanel Orientation="Horizontal">  
  18.                                   <TextBlock Text="Point" Margin="5,1,0,1"></TextBlock>  
  19.                                   <TextBlock Text="{Binding Point}" Margin="3,1,0,1"></TextBlock>  
  20.                               </StackPanel>  
  21.                           </StackPanel>  
  22.   
  23.                       </Grid>  
  24.   
  25.                   </StackPanel>  
  26.   
  27.   
  28.               </DataTemplate>  
  29.           </ListBox.ItemTemplate>  
  30.       </ListBox  >    

This common code I am using for every demo on all platforms. I am using the same code everywhere in all four platforms, Windows 8, Silverlight, WPF and Windows Phone. Just a small change I do based on platform and display. Later I will demonstrate the Portable Class Library (PCL) With MVVM in the next article and I‘ll explore more of the Silverlight Demo Application . I made a small change for the Silverlight demo. Here I used the Silverlight toolkit for WrapPanel on the View because WrapPanel is not available by default.

 WrapPanel on the View

WPF DataTemplate Demo  

Here also I changed one property, I set the Listbox scroll to Horizontal Property disabled.

WPF DataTemplate Demo 

Windows Phone DataTemplate  

Nothing I changed for the Windows Phone Sample, the same as for Windows 8 Code I copied and pasted here. 

 Windows Phone DataTemplate 

In the following image I show my source code structure . Here five executable projects and two class libraryies. Everything follows the MVVM Concept.

The minimum requirement for this project is Visual Studio 2012 and Windows Phone 8 SDK.

 Windows Phone 8 SDK