Search code examples
windows-phone-8itemtemplatelonglistselectoritemtemplateselector

LongListSelector different item template for first and last item


Im writing my Windows phone 8 app which uses LongListSelector to display some data.

How to set different item template for first and last item in LongListSelector?

Basically I just want to display same information in every item but use little different item "layout" in last and first item.


Solution

  • You could implement some kind of data template selector to help in determining which template to select based on index. You can start off by creating a reusable abstract TemplateSelector class. I used many of the ideas explained in Implementing Windows Phone 7 DataTemplateSelector and CustomDataTemplateSelector but modified implementation to allow for selecting templates based on index instead.

    public abstract class TemplateSelector : ContentControl {
      public abstract DataTemplate SelectTemplate(object item, int index, int totalCount, DependencyObject container);
    
      protected override void OnContentChanged(object oldContent, object newContent) {
        base.OnContentChanged(oldContent, newContent);
    
        var parent = GetParentByType<LongListSelector>(this);
        var index = parent.ItemsSource.IndexOf(newContent);
        var totalCount = parent.ItemsSource.Count;
    
        ContentTemplate = SelectTemplate(newContent, index, totalCount, this);
      }
    
      private static T GetParentByType<T>(DependencyObject element) where T : FrameworkElement {
        T result = null;
        DependencyObject parent = VisualTreeHelper.GetParent(element);
    
        while (parent != null) {
          result = parent as T;
    
          if (result != null) {
            return result;
          }
    
          parent = VisualTreeHelper.GetParent(parent);
        }
    
        return null;
      }
    }
    

    Once you have that class you can add your own data template selector logic. In your case, could be something like this

    public class MyTemplateSelector : TemplateSelector {
      public DataTemplate First { get; set; }
      public DataTemplate Default { get; set; }
      public DataTemplate Last { get; set; }
    
      public override DataTemplate SelectTemplate(object item, int index, int totalCount, DependencyObject container) {
        if (index == 0)
          return First;
        else if (index == totalCount-1)
          return Last;
        else
          return Default;
      }
    }
    

    And finally the Xaml

    <phone:PhoneApplicationPage.Resources>
        <DataTemplate x:Key="first">
            <TextBlock Text="{Binding Name}" Foreground="Yellow" />
        </DataTemplate>
        <DataTemplate x:Key="default">
            <TextBlock Text="{Binding Name}" />
        </DataTemplate>
        <DataTemplate x:Key="last">
            <TextBlock Text="{Binding Name}" Foreground="Red" />
        </DataTemplate>
    
        <DataTemplate x:Key="SelectingTemplate">
            <local:MyTemplateSelector Content="{Binding}"
                                    First="{StaticResource first}"
                                    Default="{StaticResource default}"
                                    Last="{StaticResource last}"
                                    HorizontalContentAlignment="Stretch" />
        </DataTemplate>
    </phone:PhoneApplicationPage.Resources>
    
    <phone:LongListSelector
                ItemTemplate="{StaticResource SelectingTemplate}"
                ItemsSource="{Binding Data}" />