Search code examples
c#winrt-xamldatatemplatewindows-8.1listboxitem

Apply multiple Datatemplates to listbox Itemtemplate based on data


I'm sure this is simple but i just cant seem to figure out how to do it. Basicly i have a list of customers that comes from a azure mobile service database. so far everything works fine but I would like to set the item template for each item in a listbox based on the data. I have 2 templates, one for companies and on for just a person. My question is how to apply each one.

Templates

<DataTemplate x:Key="CompanyItemTemplate">
    -------
</DataTemplate>

<DataTemplate x:Key="CustomerItemTemplate">
    -------
</DataTemplate>

Code

CustomerListItems.ItemsSource = customeritems.OrderBy(customer => customer.CustomerName);

foreach (Customers customer in customeritems)
{
    if (customer.Company != "")
    {
        CustomerListItems.ItemTemplate = CompanyItemTemplate;
    }
    else
    {
        CustomerListItems.ItemTemplate = CustomerItemTemplate;
    }
}

Solution

  • You can use a DataTemplateSelector to dynamically select the DataTemplate based on the data bound to your properties:

    Sample code:

    public class ImgStringTemplateSelector : DataTemplateSelector
    {
      public DataTemplate ImageTemplate { get; set; }
      public DataTemplate StringTemplate { get; set; }
    
      public override DataTemplate SelectTemplate(object item, 
        DependencyObject container)
      {
        String path = (string)item;
        String ext = System.IO.Path.GetExtension(path);
        if (System.IO.File.Exists(path) && ext == ".jpg")
          return ImageTemplate;
        return StringTemplate;
      }
    }
    
      <Window.Resources>
        <local:RelativeToAbsolutePathConverter x:Key="relToAbsPathConverter" />
    
        <DataTemplate x:Key="stringTemplate">
          <TextBlock Text="{Binding}"/>
        </DataTemplate>
    
        <DataTemplate x:Key="imageTemplate">
          <Image Source="{Binding Converter={StaticResource relToAbsPathConverter}}" 
                 Stretch="UniformToFill" Width="200"/>
        </DataTemplate>
    
        <local:ImgStringTemplateSelector 
            ImageTemplate="{StaticResource imageTemplate}" 
            StringTemplate="{StaticResource stringTemplate}" 
            x:Key="imgStringTemplateSelector" />
      </Window.Resources>
    
      <Grid>
        <ListView ScrollViewer.CanContentScroll="False" 
                  ItemsSource="{Binding ElementName=This, Path=PathCollection}" 
                  ItemTemplateSelector="{StaticResource imgStringTemplateSelector}">
        </ListView>
      </Grid>
    </Window>