如何将 ListView.ItemTapped 事件绑定到 Xamarin Forms 中的 ViewModel 命令?

How to bind a ListView.ItemTapped event to a ViewModel command in Xamarin Forms?

我正在使用 Prism 来实现 MVVM。

我有一个情况,我有一个 ListView 并且必须处理 ItemTapped 事件并获取点击的项目。

我尝试使用 EventToCommandBehavior

但我无法让它工作,因为它无法识别添加的引用。

EventToCommandBehavior 当前不存在于 NuGet 上可用的 pre1 包中。这应该在 pre2 发布时可用。

我的建议是您暂时将 EventToCommandBehavior 复制到您的项目中,或者您可以添加我使用的一个:

/// <summary>
/// ListView Item Tapped Behavior.
/// </summary>
public class ItemTappedBehavior : BehaviorBase<ListView>
{
    /// <summary>
    /// Gets or sets the command.
    /// </summary>
    /// <value>The command.</value>
    public ICommand Command { get; set; }

    /// <inheritDoc />
    protected override void OnAttachedTo( ListView bindable )
    {
        base.OnAttachedTo( bindable );
        AssociatedObject.ItemTapped += OnItemTapped;
    }

    /// <inheritDoc />
    protected override void OnDetachingFrom( ListView bindable )
    {
        base.OnDetachingFrom( bindable );
        AssociatedObject.ItemTapped -= OnItemTapped;
    }

    void OnItemTapped( object sender, ItemTappedEventArgs e )
    {
        if ( Command == null || e.Item == null ) return;

        if ( Command.CanExecute( e.Item ) )
            Command.Execute( e.Item );
    }
}

然后在你的Xaml

<ListView.Behaviors>
    <behaviors:ItemTappedBehavior Command="{Binding SelectedItemCommand}" />
</ListView.Behaviors>

我建议采用不同的方法。

public class AppListView: ListView{

    public AppListView(): base(ListViewCachingStrategy.RecycleElement){
        this.ItemSelected += (s,e)=>{
            this.TapCommand?.Invoke(e.Item);
        }
    }

    #region Property TapCommand

    /// <summary>
    /// Bindable Property TapCommand
    /// </summary>
    public static readonly BindableProperty TapCommandProperty = BindableProperty.Create(
      nameof(TapCommand),
      typeof(System.Windows.Input.ICommand),
      typeof(AppListView),
      null,
      BindingMode.OneWay,
      null,
      null,
      null,
      null,
      null
    );

    /// <summary>
    /// Property TapCommand
    /// </summary>
    public System.Windows.Input.ICommand TapCommand
    {
        get
        {
            return (System.Windows.Input.ICommand)GetValue(TapCommandProperty);
        }
        set
        {
            SetValue(TapCommandProperty, value);
        }
    }
    #endregion

}

现在使用 AppListView 而不是 ListView 并使用 TapCommand="{Binding ...}"。为了智能感知正常工作,我建议将此 class 保存在一个单独的库项目中(一个用于 android,一个用于 iOS,并将此文件保存在所有库项目之间的共享项目中) .