在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
相关产品推荐
相关产品推荐

