Windows Phone LongListSelector Control with Dynamic DataTemplates Binding

This article describes about binding the multiple data templates for a LongListSelector Control in Windows Phone application. In real time scenario, if you want to show data in multiple sections then we can create the multiple data templates and will be binded dynamically based on the section of data you are showing. Here each section will have its own datatemplate defined.

I am going to display the Latest News and Appointments for logged In user in LongListSelector Control. News section will have different format of data and Appointment section will have different format of data and styling. So I can create the different data templates for News and Appointments and will be binded dynamically.

For Windows Store, the same feature will be accomplished by using the GridView/ListView Control.

1) Create Windows Phone Project in MVVMlight and add the LongListSelector Control to MainPage.XAML and Set the LayoutMode=”List” as below.

<phone:LongListSelector   LayoutMode="List"  />

2) Create the DataTemplates for News and Appointments and DataTemplate for News and Appoinments Header as below.

<!--News Section template-->
   <DataTemplate x:Key="NewsTemplate">
            <Grid Margin="0,10,0,0">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"></RowDefinition>
                    <RowDefinition Height="Auto"></RowDefinition>
                    <RowDefinition Height="*"></RowDefinition>
                </Grid.RowDefinitions>
                <TextBlock Grid.Row="0" FontSize="28" Text="{Binding Path=Title}"></TextBlock>
            
                <TextBlock Grid.Row="1" Text="{Binding Path=Description}" TextWrapping="Wrap"></TextBlock>
                <TextBlock Grid.Row="2" Text="........................................................" ></TextBlock>
            </Grid>
        </DataTemplate>

     <!--Appointments Section template-->
        <DataTemplate x:Key="AppointmentsTemplate">
            <Grid Margin="0,10,0,0">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"></RowDefinition>
                    <RowDefinition Height="Auto"></RowDefinition>
                    <RowDefinition Height="*"></RowDefinition>
                </Grid.RowDefinitions>
                <TextBlock Grid.Row="0" FontSize="28" Text="{Binding Path=Title}"></TextBlock>
                <TextBlock Grid.Row="1" Text="{Binding Path=Time}" TextWrapping="Wrap"></TextBlock>
                <TextBlock Grid.Row="2" Text="........................................................" ></TextBlock>
            </Grid>
        </DataTemplate>

       <!--Section Header template-->
        <DataTemplate x:Key="HeaderTemplate">
            <TextBlock Margin="0,10,0,0" FontSize="40" Text="{Binding Path=Title}"></TextBlock>
        </DataTemplate>
    
3) Create an interface “IWhatsNewItem.cs” with Properties

  public interface IWhatsNewItem
    {
        string Title { get; set; }

        string Description { get; set; }

        string Time { get; set; }
    }

4) Create models for News and Appointments and implement the interface members by inheriting in to created models.

public class NewsWhatsNewItem : IWhatsNewItem
    {
        public string Title { get; set; }

        public string Description { get; set; }

        public string Time { get; set; }
    }

public class AppointmentWhatsNewItem : IWhatsNewItem
    {
        public string Title { get; set; }

        public string Description { get; set; }

        public string Time { get; set; }
    }

5) Define the property with ObservableCollection<IWhatsNewItem> in MainViewModel and fill with required data.

public ObservableCollection<IWhatsNewItem> WhatsNewItems
        {
            get
            {
                return this.whatsNewItems;
            }

            set
            {
                this.whatsNewItems = value;
                this.RaisePropertyChanged(() => this.WhatsNewItems);
            }
        }

        private void LoadLatestNewsAppointments()
        {
            this.WhatsNewItems.Add(new AppointmentWhatsNewItem { Title = "Appointments" });
            this.WhatsNewItems.Add(new AppointmentWhatsNewItem { Title = "Daily SyncUp Meeting", Time = "10:00 AM - 11:00 AM" });
            this.WhatsNewItems.Add(new AppointmentWhatsNewItem { Title = "Training", Time = "02:00 PM - 03:00 PM" });
            this.WhatsNewItems.Add(new NewsWhatsNewItem { Title = "News" });
            this.WhatsNewItems.Add(new NewsWhatsNewItem { Title = "News Item 1", Description = "This section contains the latest news with the description" });
            this.WhatsNewItems.Add(new NewsWhatsNewItem { Title = "News Item 2", Description = "Please attend the meeting as scheduled in the Appointments section" });
        }

6) Create a class TemplateSelector.cs, inherit from ContentControl and implement the “OnContentChanged” method to set the SelectedTemplate for a Control as below.

public abstract class TemplateSelector : ContentControl
    {
        public abstract DataTemplate SelectTemplate(object item, DependencyObject container);

        protected override void OnContentChanged(object oldContent, object newContent)
        {
            base.OnContentChanged(oldContent, newContent);

            ContentTemplate = SelectTemplate(newContent, this);
        }
    }

7) Create a Class ListTemplateSelector.cs, inherit from TemplateSelector and add the DataTemplates to be binded as properties and return the required datatemplate to be binded based on the type of Model.

public class ListTemplateSelector : TemplateSelector
    {
        public DataTemplate NewsTemplate { get; set; }

        public DataTemplate AppointmentsTemplate { get; set; }

        public DataTemplate HeaderTemplate { get; set; }

        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            var newItem = item as NewsWhatsNewItem;
            if (newItem != null)
            {
                if (newItem.Title == "News")
                {
                    
                    return HeaderTemplate;
                }

                return NewsTemplate;
            }

            return ((AppointmentWhatsNewItem)item).Title == "Appointments" ? this.HeaderTemplate : this.AppointmentsTemplate;
        }
    }

8) Now add the ItemTemplate for LongListSelector Control and Bind the DataTemplates as below.

<phone:LongListSelector ItemsSource="{Binding WhatsNewItems}"
                                    LayoutMode="List" Background="Transparent"
                                    >
                <phone:LongListSelector.ItemTemplate>
                    <DataTemplate>
                        <common:ListTemplateSelector Content="{Binding}" HorizontalContentAlignment="Left"
                                                     HeaderTemplate="{StaticResource HeaderTemplate}"
                                                     NewsTemplate="{StaticResource NewsTemplate}"
                                                     AppointmentsTemplate="{StaticResource AppointmentsTemplate}"></common:ListTemplateSelector>
                     </DataTemplate>
                  </phone:LongListSelector.ItemTemplate>
                 
            </phone:LongListSelector>

Now press F5 to run the App.

Note: If you want to run this application, the system specifications are Windows 8 ans VS 2013 with Phone SDK installed.
                                   
 Please download the sample from below url
http://nullskull.com/FileUpload/-407123783_WPLongListSelectorWithDataTemplate.zip  


By Siva Jagan Dhulipalla   Popularity  (4507 Views)