如何将 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,并将此文件保存在所有库项目之间的共享项目中) .
我正在使用 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,并将此文件保存在所有库项目之间的共享项目中) .