【问题标题】:How to bind a ListView.ItemTapped event to a ViewModel command in Xamarin Forms?如何将 ListView.ItemTapped 事件绑定到 Xamarin Forms 中的 ViewModel 命令?
【发布时间】:2017-06-15 04:59:06
【问题描述】:

我正在使用 Prism 来实现 MVVM。

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

我尝试使用EventToCommandBehavior

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

【问题讨论】:

    标签: xamarin mvvm xamarin.forms prism


    【解决方案1】:

    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>
    

    【讨论】:

      【解决方案2】:

      我会建议一种不同的方法。

      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 ...}"。为了使智能感知正常工作,我建议将此类保存在单独的库项目中(一个用于 android,一个用于 iOS,并将此文件保存在所有库项目之间的共享项目中)。

      【讨论】:

      • 为什么要采用不同的方法?
      猜你喜欢
      • 2017-10-19
      • 1970-01-01
      • 2016-10-18
      • 2011-06-21
      • 2017-01-15
      • 1970-01-01
      • 2015-06-21
      • 2015-10-30
      • 2012-06-17
      相关资源
      最近更新 更多