You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在UWP ListView中显示两种自定义数据模板(VS2017环境)

在UWP ListView中使用两种自定义DataTemplate展示不同类型列表项

嗨,针对你用VS2017开发UWP时,需要在ListView里展示两种不同类型列表项的需求,我给你整理了一套完整的实现方案,亲测有效:

第一步:定义数据模型

首先得给两种不同的列表项创建对应的实体类,建议先搞一个基类,再派生出两个子类,这样方便后续模板选择器识别:

// 消息基类
public class MessageBase
{
    public string Content { get; set; }
    public DateTime SendTime { get; set; }
}

// 自己发送的消息
public class SentMessage : MessageBase
{
    public string SenderAvatar { get; set; }
}

// 收到的消息
public class ReceivedMessage : MessageBase
{
    public string ReceiverAvatar { get; set; }
}

第二步:创建自定义DataTemplateSelector

这是实现不同模板切换的核心,它会根据数据项的类型自动选择对应的模板:

using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace InboxModule
{
    public class MessageTemplateSelector : DataTemplateSelector
    {
        public DataTemplate SentMessageTemplate { get; set; }
        public DataTemplate ReceivedMessageTemplate { get; set; }

        protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
        {
            if (item is SentMessage)
            {
                return SentMessageTemplate;
            }
            else if (item is ReceivedMessage)
            {
                return ReceivedMessageTemplate;
            }
            return base.SelectTemplateCore(item, container);
        }
    }
}

第三步:在XAML页面中配置模板和Selector

接下来把你的ListView和两种模板整合起来,注意要先声明自定义Selector的命名空间:

<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="SentMessageTemplate">
            <Grid Margin="0,8" HorizontalAlignment="Right">
                <StackPanel Orientation="Horizontal">
                    <Image Source="{Binding SenderAvatar}" Width="40" Height="40" CornerRadius="20"/>
                    <Border Background="#E0F2FE" CornerRadius="16,16,4,16" Padding="12,8">
                        <StackPanel>
                            <TextBlock Text="{Binding Content}" FontSize="14" MaxWidth="250"/>
                            <TextBlock Text="{Binding SendTime, StringFormat='{}{0:HH:mm}'}" FontSize="12" Foreground="#666666" Margin="0,4,0,0" HorizontalAlignment="Right"/>
                        </StackPanel>
                    </Border>
                </StackPanel>
            </Grid>
        </DataTemplate>

        <!-- 收到消息的模板 -->
        <DataTemplate x:Key="ReceivedMessageTemplate">
            <Grid Margin="0,8" HorizontalAlignment="Left">
                <StackPanel Orientation="Horizontal">
                    <Image Source="{Binding ReceiverAvatar}" Width="40" Height="40" CornerRadius="20"/>
                    <Border Background="#F5F5F5" CornerRadius="16,16,16,4" Padding="12,8">
                        <StackPanel>
                            <TextBlock Text="{Binding Content}" FontSize="14" MaxWidth="250"/>
                            <TextBlock Text="{Binding SendTime, StringFormat='{}{0:HH:mm}'}" FontSize="12" Foreground="#666666" Margin="0,4,0,0" HorizontalAlignment="Left"/>
                        </StackPanel>
                    </Border>
                </StackPanel>
            </Grid>
        </DataTemplate>

        <!-- 自定义模板选择器 -->
        <local:MessageTemplateSelector x:Key="MessageTemplateSelector"
                                       SentMessageTemplate="{StaticResource SentMessageTemplate}"
                                       ReceivedMessageTemplate="{StaticResource ReceivedMessageTemplate}"/>
    </Page.Resources>

    <Grid>
        <ListView ItemsSource="{Binding Messages}"
                  ItemTemplateSelector="{StaticResource MessageTemplateSelector}"
                  ScrollViewer.VerticalScrollBarVisibility="Auto"
                  Margin="16">
            <!-- 可以根据需要设置ListView的其他属性,比如ItemContainerStyle等 -->
        </ListView>
    </Grid>
</Page>

第四步:准备数据源并绑定

最后在页面的代码后台或者ViewModel里准备包含两种类型消息的集合,绑定到ListView的ItemsSource:

using Windows.UI.Xaml.Controls;
using System.Collections.ObjectModel;

namespace InboxModule
{
    public sealed partial class ChatMessages : Page
    {
        public ObservableCollection<MessageBase> Messages { get; set; }

        public ChatMessages()
        {
            this.InitializeComponent();
            this.DataContext = this;

            // 模拟测试数据
            Messages = new ObservableCollection<MessageBase>
            {
                new ReceivedMessage { Content = "你好呀!", ReceiverAvatar = "ms-appx:///Assets/ReceiverAvatar.png", SendTime = DateTime.Now.AddMinutes(-10) },
                new SentMessage { Content = "嗨,我来了!", SenderAvatar = "ms-appx:///Assets/SenderAvatar.png", SendTime = DateTime.Now.AddMinutes(-9) },
                new ReceivedMessage { Content = "今天有什么需求吗?", ReceiverAvatar = "ms-appx:///Assets/ReceiverAvatar.png", SendTime = DateTime.Now.AddMinutes(-8) },
                new SentMessage { Content = "我想在ListView里展示两种不同的模板", SenderAvatar = "ms-appx:///Assets/SenderAvatar.png", SendTime = DateTime.Now.AddMinutes(-7) }
            };
        }
    }
}

这样一来,ListView就会自动根据每个消息的类型,选择对应的DataTemplate来渲染啦!你可以根据自己的UI需求调整模板里的布局和样式,比如修改边框颜色、字体大小这些。

内容的提问来源于stack exchange,提问作者iuhettiarachchi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:35:05