Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I'm using Prism to implement MVVM.

And I have a situation where I have a ListView and have to handle the ItemTapped event and also get the tapped item.

I tried using EventToCommandBehavior.

But I couldn't get it to work cause it was not recognising the references that were added.

like image 664
AbsoluteSith Avatar asked Jan 30 '17 04:01

AbsoluteSith


People also ask

How do I bind a list view in xamarin?

Using Binding with Classes cs” and added two attributes. After adding the class, now create a tag of the list in ListView and we will bind the attributes to the ListView using text cell. Item template is used for visualization of the data objects. Data template tells what kind of data we are going to utilize.

How do you bind property in xamarin forms?

The binding references the source object. To set the data binding, use the following two members of the target class: The BindingContext property specifies the source object. The SetBinding method specifies the target property and source property.

How do you implement ListView in xamarin forms?

Data Template contains the data of the list. Put a ViewCell in it and add Three labels with a image. To add the image just simply copy it and paste outside to your UWP or Android project and add the reference to your tag. And bind each of them with the same name of the property in contacts class.


2 Answers

The EventToCommandBehavior does not currently exist in the pre1 package available on NuGet. This should be available when pre2 is released.

My recommendation would be that you either copy the EventToCommandBehavior to your project for now, or you could add one that I use:

/// <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 );
    }
}

Then in your Xaml

<ListView.Behaviors>
    <behaviors:ItemTappedBehavior Command="{Binding SelectedItemCommand}" />
</ListView.Behaviors>
like image 167
Dan Siegel Avatar answered Oct 16 '22 16:10

Dan Siegel


I would suggest a different approach.

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

}

Now use AppListView instead of ListView and use TapCommand="{Binding ...}". In order for intellisense to work correctly, I suggest keep this class in a separate library project (one for android, one for iOS and keep this file in shared project between all library projects).

like image 2
Akash Kava Avatar answered Oct 16 '22 14:10

Akash Kava