简体   繁体   中英

Display different data templates on a list view in UWP

I am working with visual studio 2017. And I wand to display two type of list view items in a list view. That means two different custom data templates. And This is my xaml page

<Page
    x:Class="InboxModule.ChatMessages"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:InboxModule"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Page.Resources>

        <DataTemplate x:Key="leftTemplate">
            <StackPanel Background="Aqua" Orientation="Horizontal">
                <TextBlock Text="left"/>
                <TextBlock Text="{Binding LastMessage}"/>
            </StackPanel>
        </DataTemplate>

        <DataTemplate x:Key="rightTemplate">
            <Grid Background="White">
                <TextBlock Text="right"/>
            </Grid>
        </DataTemplate>

        <local:MyDataTemplateSelector x:Key="myPremiumUserDataTemplateSelector" />
    </Page.Resources>

    <Grid>
        <ListView x:Name="myListView" ItemTemplateSelector="{StaticResource myPremiumUserDataTemplateSelector}">
        </ListView>                 
    </Grid>
</Page>

And my xaml.cs code is this

public sealed partial class ChatMessages : Page
{
    public ChatMessages()
    {
        this.InitializeComponent();

        List<chat> users = new List<chat>();
        for (int i = 0; i < 10; ++i)
        {
            var user = new chat { NewMessages = "Name is mj "};

            if (i == 2 || i == 4)
            {
                user.Name = "Alex Doe";
            }
            users.Add(user);
        }
        myListView.ItemsSource = users;
    }

    private void BackButton_Click(object sender, RoutedEventArgs e)
    {
        Frame.Navigate(typeof(InboxChat));
    }
}

And my MyDataTemplateSelector class is this

public class MyDataTemplateSelector : DataTemplateSelector
{
    protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
    {
        FrameworkElement elemnt = container as FrameworkElement;
        chat user = item as chat;
        if (user.Name == "Alex Doe")
        {
            return elemnt.FindName("leftTemplate") as DataTemplate;
        }
        else
        {
            return elemnt.FindName("rightTemplate") as DataTemplate;
        }       
    }
}

I tried to use dummy values. And i have tried for hours.. but i could not find a solution. Please help me to solve this problem. Thank you very much!!

I think you need to pass the data templates to the selector when it is initialized in the view XAML. Here is how to do it.

You selector will look like this (basically accepting the data templates as properties in the class):

public class MyDataTemplateSelector : DataTemplateSelector
    {
        public DataTemplate DataTemplate1 { get; set; }

        public DataTemplate DataTemplate2 { get; set; }

        protected override DataTemplate SelectTemplateCore(object item)
        {
            if ([Condition 1] == true)
                return DataTemplate1;

            if ([Condition 2] == true)
                return DataTemplate2;

            return base.SelectTemplateCore(item);
        }

        protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
        {
            return SelectTemplateCore(item);
        }
    }

Then to use this selector, declare it like this in your view's XAML:

<Page.Resources>
    <MyDataTemplateSelector x:Key="MySelector">
      <MyDataTemplateSelector.DataTemplate1>
           <DataTemplate .... />
      <MyDataTemplateSelector.DataTemplate1>

      <MyDataTemplateSelector.DataTemplate2>
           <DataTemplate .... />
      <MyDataTemplateSelector.DataTemplate2>
    </MyDataTemplateSelector>
</Page.Resources>

you will basically be declaring those data templates inside the xaml code initializing your selector.

Edit: As for the reason your code wasn't working: I suspect this is because it can't find the element you are looking for with FindName and is probably returning a null data template back to the list view using this selector.

Hope this helps you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM