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

如何将现有RadListView定义为资源以在多页面复用并绑定不同数据源?

复用RadListView作为可复用资源的最优方案

要实现你这个RadListView的复用(包括它的ItemTemplate和基础配置),最干净高效的方式是把它封装成自定义控件,这样其他页面直接引用就能用,不用重复写一大段模板代码。下面给你两种可行方案,你可以根据自己的需求选择:

方案一:封装成自定义RadListView控件(推荐)

这种方案把整个ListView的布局、模板和预设属性都封装起来,只对外暴露需要动态绑定的属性(比如ItemsSource、SelectedItem、HeightRequest),完美适配你的需求——复用整个ListView,只换数据源。

第一步:创建自定义控件的XAML文件

新建一个名为ReusableStudyListView.xaml的文件,把你的ListView模板和配置放进去:

<?xml version="1.0" encoding="UTF-8"?>
<dataControls:RadListView xmlns="http://xamarin.com/schemas/2014/forms"
                         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                         xmlns:dataControls="clr-namespace:Telerik.XamarinForms.DataControls;assembly=Telerik.XamarinForms.DataControls"
                         xmlns:listView="clr-namespace:Telerik.XamarinForms.DataControls.ListView;assembly=Telerik.XamarinForms.DataControls"
                         xmlns:maxline="clr-namespace:YourAppNamespace" <!-- 替换成XfMaxLinesLabel所在的命名空间 -->
                         x:Class="YourAppNamespace.ReusableStudyListView"
                         MinimumHeightRequest="70"
                         x:Name="InternalListView">
    <dataControls:RadListView.ItemTemplate>
        <DataTemplate>
            <listView:ListViewTemplateCell>
                <listView:ListViewTemplateCell.View>
                    <Grid Padding="2,2,2,5" HorizontalOptions="FillAndExpand">
                        <StackLayout Padding="5,1,1,5" Grid.Column="0">
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*"/>
                                    <ColumnDefinition Width="Auto"/>
                                </Grid.ColumnDefinitions>
                                <maxline:XfMaxLinesLabel MaxLines="2" 
                                                         Text="{Binding BriefTitle, Mode=TwoWay}" 
                                                         Style="{StaticResource ListViewLabelStyle}" 
                                                         TextColor="Black"/>
                            </Grid>
                            <StackLayout Padding="0,0,0,0" HorizontalOptions="Fill">
                                <BoxView Margin="0" BackgroundColor="Gray" HeightRequest=".25" />
                                <Label Text="{Binding ClosestFacility.Name, Mode=TwoWay}" 
                                       Style="{StaticResource ListViewLabelStyle}"/>
                                <BoxView Margin="0" BackgroundColor="Gray" HeightRequest=".25" />
                            </StackLayout>
                        </StackLayout>
                    </Grid>
                </listView:ListViewTemplateCell.View>
            </listView:ListViewTemplateCell>
        </DataTemplate>
    </dataControls:RadListView.ItemTemplate>
</dataControls:RadListView>

第二步:编写自定义控件的后台代码

新建对应的后台文件ReusableStudyListView.xaml.cs,把需要外部绑定的属性暴露出来,和内部的ListView关联:

using Xamarin.Forms;
using Telerik.XamarinForms.DataControls;

namespace YourAppNamespace
{
    public partial class ReusableStudyListView : RadListView
    {
        // 定义可绑定的ItemsSource属性
        public static readonly BindableProperty ItemsSourceProperty =
            BindableProperty.Create(nameof(ItemsSource), typeof(object), typeof(ReusableStudyListView), null,
                propertyChanged: (bindable, oldValue, newValue) =>
                {
                    var control = (ReusableStudyListView)bindable;
                    control.InternalListView.ItemsSource = newValue;
                });

        // 定义可绑定的SelectedItem属性(双向绑定)
        public static readonly BindableProperty SelectedItemProperty =
            BindableProperty.Create(nameof(SelectedItem), typeof(object), typeof(ReusableStudyListView), null,
                BindingMode.TwoWay,
                propertyChanged: (bindable, oldValue, newValue) =>
                {
                    var control = (ReusableStudyListView)bindable;
                    control.InternalListView.SelectedItem = newValue;
                });

        // 定义可绑定的HeightRequest属性
        public static readonly BindableProperty HeightRequestProperty =
            BindableProperty.Create(nameof(HeightRequest), typeof(double), typeof(ReusableStudyListView), 0.0,
                propertyChanged: (bindable, oldValue, newValue) =>
                {
                    var control = (ReusableStudyListView)bindable;
                    control.InternalListView.HeightRequest = (double)newValue;
                });

        // 属性的get/set方法
        public object ItemsSource
        {
            get => GetValue(ItemsSourceProperty);
            set => SetValue(ItemsSourceProperty, value);
        }

        public object SelectedItem
        {
            get => GetValue(SelectedItemProperty);
            set => SetValue(SelectedItemProperty, value);
        }

        public new double HeightRequest
        {
            get => (double)GetValue(HeightRequestProperty);
            set => SetValue(HeightRequestProperty, value);
        }

        public ReusableStudyListView()
        {
            InitializeComponent();
            // 同步内部ListView的选中变化到外部属性
            InternalListView.SelectedItemChanged += (s, e) => SelectedItem = InternalListView.SelectedItem;
        }
    }
}

第三步:在其他页面复用这个自定义控件

现在你可以在任何页面里直接用这个控件,只需要绑定对应的数据源和属性就行:

<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:controls="clr-namespace:YourAppNamespace" <!-- 替换成自定义控件所在的命名空间 -->
             x:Class="YourAppNamespace.YourTargetPage">
    <StackLayout>
        <!-- 直接引用自定义控件,绑定需要的属性 -->
        <controls:ReusableStudyListView ItemsSource="{Binding YourOtherStudyResults}"
                                        SelectedItem="{Binding YourSelectedItem, Mode=TwoWay}"
                                        HeightRequest="{Binding YourListHeight}"/>
    </StackLayout>
</ContentPage>

方案二:将ItemTemplate作为全局资源(灵活复用模板)

如果你只是想复用ItemTemplate,而ListView的其他属性(比如HeightRequest)在不同页面需要调整,可以把模板放到全局资源字典里:

第一步:在App.xaml中添加全局模板

<Application.Resources>
    <ResourceDictionary>
        <!-- 你的其他静态资源(比如ListViewLabelStyle) -->
        <DataTemplate x:Key="StudyItemTemplate">
            <listView:ListViewTemplateCell>
                <listView:ListViewTemplateCell.View>
                    <Grid Padding="2,2,2,5" HorizontalOptions="FillAndExpand">
                        <StackLayout Padding="5,1,1,5" Grid.Column="0">
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*"/>
                                    <ColumnDefinition Width="Auto"/>
                                </Grid.ColumnDefinitions>
                                <maxline:XfMaxLinesLabel MaxLines="2" 
                                                         Text="{Binding BriefTitle, Mode=TwoWay}" 
                                                         Style="{StaticResource ListViewLabelStyle}" 
                                                         TextColor="Black"/>
                            </Grid>
                            <StackLayout Padding="0,0,0,0" HorizontalOptions="Fill">
                                <BoxView Margin="0" BackgroundColor="Gray" HeightRequest=".25" />
                                <Label Text="{Binding ClosestFacility.Name, Mode=TwoWay}" 
                                       Style="{StaticResource ListViewLabelStyle}"/>
                                <BoxView Margin="0" BackgroundColor="Gray" HeightRequest=".25" />
                            </StackLayout>
                        </StackLayout>
                    </Grid>
                </listView:ListViewTemplateCell.View>
            </listView:ListViewTemplateCell>
        </DataTemplate>
    </ResourceDictionary>
</Application.Resources>

第二步:在页面中使用这个模板

<dataControls:RadListView x:Name="ItemsListView" 
                          ItemsSource="{Binding YourStudyResults, Mode=TwoWay}" 
                          MinimumHeightRequest="70" 
                          HeightRequest="{Binding YourHeight}" 
                          SelectedItem="{Binding YourSelectedItem, Mode=TwoWay}"
                          ItemTemplate="{StaticResource StudyItemTemplate}"/>

方案对比

  • 自定义控件方案:封装最彻底,完全复用整个ListView的配置,页面代码最简洁,还能保证所有使用该控件的页面UI一致,强烈推荐。
  • 全局模板方案:更灵活,适合需要在不同页面调整ListView其他属性的场景,但页面中还是要写ListView的基础配置代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 12:02:44