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

在MVVM模式的Xamarin.Forms中从独立文件ItemTemplate获取选中项

在MVVM架构的Xamarin.Forms中实现独立ItemTemplate选中项获取

我来帮你搞定这个问题,结合你用的Prism框架,给你一套完整的实现方案,先把你提供的页面XAML补全并整理好,再一步步讲实现逻辑:

第一步:整理页面XAML(包含使用独立ItemTemplate的列表控件)

假设你的页面里用的是ListView(如果是CollectionView逻辑完全一致),把独立的ItemTemplate通过StaticResource引用进来,同时绑定SelectedItem到ViewModel的属性:

<?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:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
             xmlns:view="clr-namespace:Fuse.ViewTemplates;assembly=Fuse"
             prism:ViewModelLocator.AutowireViewModel="True"
             x:Class="Fuse.Views.JoinPage">
    <StackLayout Orientation="Vertical">
        <Label Text="Games near your area .. " VerticalOptions="Start" />
        <!-- 引用独立的ItemTemplate,绑定数据源和选中项 -->
        <ListView x:Name="GamesListView"
                  ItemsSource="{Binding NearbyGames}"
                  ItemTemplate="{StaticResource GameItemTemplate}"
                  SelectedItem="{Binding SelectedGame, Mode=TwoWay}">
        </ListView>
    </StackLayout>
</ContentPage>

第二步:独立的ItemTemplate定义

把你的ItemTemplate放在全局资源里(比如App.xaml或者单独的ResourceDictionary文件),示例如下:

<!-- 比如在App.xaml的ResourceDictionary中定义 -->
<ResourceDictionary>
    <DataTemplate x:Key="GameItemTemplate">
        <ViewCell>
            <StackLayout Padding="12" Spacing="4">
                <Label Text="{Binding GameName}" FontSize="Medium" FontAttributes="Bold" />
                <Label Text="{Binding Distance}" FontSize="Small" TextColor="#666666" />
                <!-- 可以添加更多展示控件 -->
            </StackLayout>
        </ViewCell>
    </DataTemplate>
</ResourceDictionary>

第三步:ViewModel中实现选中项的处理

因为你用了Prism,所以ViewModel继承BindableBase,通过双向绑定获取选中项,同时可以处理选中后的逻辑:

using Prism.Mvvm;
using Prism.Commands;
using System.Collections.ObjectModel;
using Fuse.Models; // 这里替换成你的游戏数据模型命名空间

namespace Fuse.ViewModels
{
    public class JoinPageViewModel : BindableBase
    {
        // 选中的游戏项
        private Game _selectedGame;
        public Game SelectedGame
        {
            get => _selectedGame;
            // SetProperty是Prism提供的属性变更通知方法,同时触发选中后的逻辑
            set => SetProperty(ref _selectedGame, value, OnSelectedGameChanged);
        }

        // 页面展示的数据源
        public ObservableCollection<Game> NearbyGames { get; set; }

        // 如果需要在ItemTemplate内添加按钮点击,用这个命令
        public DelegateCommand<Game> JoinGameCommand { get; }

        public JoinPageViewModel()
        {
            // 初始化命令和数据源
            JoinGameCommand = new DelegateCommand<Game>(ExecuteJoinGameCommand);
            NearbyGames = new ObservableCollection<Game>();
            // 这里可以调用服务加载附近的游戏数据
        }

        // 选中项变更时触发的逻辑
        private void OnSelectedGameChanged()
        {
            if (SelectedGame != null)
            {
                // 这里写你需要的逻辑,比如导航到游戏详情页、弹出确认框等
                System.Diagnostics.Debug.WriteLine($"选中了游戏:{SelectedGame.GameName}");
                
                // 可选:如果需要点击后取消选中状态,避免重复触发
                SelectedGame = null;
            }
        }

        // ItemTemplate内按钮的点击逻辑(可选)
        private void ExecuteJoinGameCommand(Game game)
        {
            if (game != null)
            {
                // 处理加入游戏的逻辑,game就是当前点击的项
                System.Diagnostics.Debug.WriteLine($"准备加入游戏:{game.GameName}");
            }
        }
    }
}

额外补充:ItemTemplate内添加按钮的绑定方式

如果你需要在独立的ItemTemplate里加按钮(比如“加入游戏”按钮),可以通过BindingContext引用页面的ViewModel命令,把当前项作为参数传递:

<DataTemplate x:Key="GameItemTemplate">
    <ViewCell>
        <StackLayout Padding="12" Spacing="4" Orientation="Horizontal">
            <StackLayout HorizontalOptions="StartAndExpand">
                <Label Text="{Binding GameName}" FontSize="Medium" FontAttributes="Bold" />
                <Label Text="{Binding Distance}" FontSize="Small" TextColor="#666666" />
            </StackLayout>
            <Button Text="加入" 
                    Command="{Binding BindingContext.JoinGameCommand, Source={x:Reference GamesListView}}"
                    CommandParameter="{Binding .}" />
        </StackLayout>
    </ViewCell>
</DataTemplate>

这样不管是点击整个列表项,还是点击ItemTemplate内的按钮,都能完美获取到选中的项,完全符合MVVM的架构要求,不需要在Code-Behind里写任何逻辑~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:33:17