.NET MAUI中如何组合ListView的DataTemplate实现可复用组件?
可复用ListView组件滚动卡顿优化方案
问题说明
需实现一款自带固定静态内容、允许用户自定义部分区域的可复用ListView组件。现有实现通过在DataTemplate中嵌套BindableLayout+转换器的方式加载自定义模板,但滚动时出现明显卡顿现象。
原实现卡顿原因
- 转换器
DataTemplateItemSourceConverter每次绑定都会创建新的ObservableCollection对象,ListView滚动复用Item时频繁触发对象创建,引发GC压力 - 嵌套的BindableLayout增加了UI布局层级,提升了渲染复杂度
优化方案
移除BindableLayout与转换器,改用ContentPresenter直接加载自定义模板,简化布局结构并减少不必要的对象创建。
优化后的自定义ListView XAML
<ListView x:Class="ReusableListView.CustomListView" xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Name="this"> <ListView.ItemTemplate> <DataTemplate> <ViewCell> <Grid ColumnDefinitions="Auto, Auto, *" RowDefinitions="*, *"> <!-- 内置静态内容:复选框 --> <CheckBox Grid.RowSpan="2" Grid.Column="0" HorizontalOptions="Center" VerticalOptions="Center" /> <!-- 内置静态内容:分隔线 --> <BoxView Grid.RowSpan="2" Grid.Column="1" BackgroundColor="LightGray" WidthRequest="1" /> <!-- 用户自定义内容区域 --> <ContentPresenter Grid.RowSpan="2" Grid.Column="2" Content="{Binding}" ContentTemplate="{Binding PartialTemplate, Source={x:Reference this}}" VerticalOptions="Center" Padding="4,0,0,0" /> </Grid> </ViewCell> </DataTemplate> </ListView.ItemTemplate> </ListView>
自定义ListView代码后置(无需修改)
public partial class CustomListView : ListView { public CustomListView() { InitializeComponent(); } static CustomListView() { PartialTemplateProperty = BindableProperty.Create(nameof(PartialTemplate), typeof(DataTemplate), typeof(CustomListView)); } public static readonly BindableProperty PartialTemplateProperty; public DataTemplate PartialTemplate { get => (DataTemplate)base.GetValue(PartialTemplateProperty); set => base.SetValue(PartialTemplateProperty, value); } }
移除冗余文件
删除DataTemplateItemSourceConverter类,该转换器已不再需要。
主页面使用方式(保持不变)
XAML:
<ContentPage x:Class="ReusableListView.MainPage" xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:lv="clr-namespace:ReusableListView"> <lv:CustomListView ItemsSource="{Binding Data}"> <lv:CustomListView.PartialTemplate> <DataTemplate> <Label VerticalOptions="Center"> <Label.Text> <MultiBinding StringFormat="{}Item Id: {0}"> <Binding Path="Id" /> </MultiBinding> </Label.Text> </Label> </DataTemplate> </lv:CustomListView.PartialTemplate> </lv:CustomListView> </ContentPage>
代码后置:
public partial class MainPage : ContentPage { public ObservableCollection<Data> Data { get; set; } public MainPage() { InitializeComponent(); BindingContext = this; Data = new(Enumerable.Range(0, 100).Select(x => new Data() { Id = Guid.NewGuid() })); OnPropertyChanged(nameof(Data)); } } public class Data { public Guid Id { get; set; } }
优化效果
- 消除了频繁创建
ObservableCollection带来的GC压力 - 简化布局层级,降低UI渲染负载
- ListView滚动流畅度明显提升,无卡顿现象
内容的提问来源于stack exchange,提问作者rsnate
相关产品推荐
相关产品推荐

