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

使用TouchBehavior时LongPressCommandParameter始终传递相同参数的问题

问题描述

按压或长按操作触发对应方法时,无论调用多少次,始终传递首次选中的元素。例如,选择分类"1"后返回分类页面,后续选择任意分类,按压和长按操作都会传递分类"1"的对象。

相关代码

CategoryViewModel.cs

[ObservableProperty]
private ObservableCollection<Category> _categories = new();

[RelayCommand]
async Task AddOperation(Category category)
{
    await Shell.Current.GoToAsync(nameof(AddOperationPage), new Dictionary<string, object>
    {
        { "choosencategory", category }
    });
}

Category.xaml

<CollectionView x:Name="collectionView" ItemsSource="{Binding Categories}"
            ItemsLayout="VerticalGrid, 2"
            SelectedItem="{Binding SelectedCategory}">
<CollectionView.ItemTemplate>
    <DataTemplate x:DataType="models:Category">
        <Border BackgroundColor="White"
                StrokeShape="RoundRectangle 40"
                StrokeThickness="2"
                Stroke="{StaticResource Primary}"
                Margin="10">
            <Grid ColumnDefinitions="0.3*,0.7*" RowDefinitions="0.5*,0.5*">
                <Grid.Behaviors>
                    <toolkit:TouchBehavior Command="{Binding Source={x:Reference collectionView}, Path=BindingContext.AddOperationCommand}"
                                           CommandParameter="{Binding .}"
                                           LongPressDuration="800"
                                           LongPressCommand="{Binding Source={x:Reference collectionView}, Path=BindingContext.ChangeCategoryCommand}"
                                           LongPressCommandParameter="{Binding .}"/>

                </Grid.Behaviors>
                <Border Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" Grid.ColumnSpan="1" Style="{StaticResource BorderCategory}" Padding="10" StrokeThickness="2" Stroke="Black">
                    <Image  Source="{Binding IconPath}" Margin="10">
                        <Image.Behaviors>
                            <toolkit:IconTintColorBehavior TintColor="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource Black}}"/>
                        </Image.Behaviors>
                    </Image>
                </Border>
                <Label Grid.Column="1" Grid.Row="0" Text="{Binding Name}" TextColor="Black" HorizontalOptions="Center"/>
                <Label Grid.Column="1" Grid.Row="1" Text="{Binding Count}" TextColor="Black" HorizontalOptions="Center"/>
            </Grid>
        </Border>
    </DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>

解决方案

1. 重置选中状态

让ViewModel实现INavigatedAware接口,在返回分类页面时清空选中项,避免状态残留:

public class CategoryViewModel : ObservableObject, INavigatedAware
{
    [ObservableProperty]
    private ObservableCollection<Category> _categories = new();

    [ObservableProperty]
    private Category? _selectedCategory;

    [RelayCommand]
    async Task AddOperation(Category category)
    {
        await Shell.Current.GoToAsync(nameof(AddOperationPage), new Dictionary<string, object>
        {
            { "choosencategory", category }
        });
    }

    public void OnNavigatedTo(NavigatedToEventArgs args)
    {
        SelectedCategory = null;
    }

    public void OnNavigatedFrom(NavigatedFromEventArgs args)
    {
        SelectedCategory = null;
    }
}

2. 强制命令参数单向绑定

修改TouchBehavior的参数绑定,显式设置Mode=OneWay,确保每次操作获取当前项的最新绑定:

<toolkit:TouchBehavior Command="{Binding Source={x:Reference collectionView}, Path=BindingContext.AddOperationCommand}"
                       CommandParameter="{Binding ., Mode=OneWay}"
                       LongPressDuration="800"
                       LongPressCommand="{Binding Source={x:Reference collectionView}, Path=BindingContext.ChangeCategoryCommand}"
                       LongPressCommandParameter="{Binding ., Mode=OneWay}"/>

3. 检查ViewModel实例生命周期

确认CategoryViewModel不是不必要的单例模式,若为单例需确保每次进入页面时重置状态,避免旧数据残留。

4. 刷新CollectionView绑定(可选)

若上述方法无效,可在页面OnAppearing中重新设置ItemsSource,触发ItemTemplate重建:

public partial class CategoryPage : ContentPage
{
    private CategoryViewModel _viewModel;

    public CategoryPage(CategoryViewModel viewModel)
    {
        InitializeComponent();
        _viewModel = viewModel;
        BindingContext = viewModel;
    }

    protected override void OnAppearing()
    {
        base.OnAppearing();
        collectionView.ItemsSource = null;
        collectionView.ItemsSource = _viewModel.Categories;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 17:34:54