title: Xamarin MVVM, binding ListView item as command parameter
body: <p>I have a ListView populated from a viewmodel an I can now easily bind elements of the datatemplate to properties of the datasource items and send those properties to a command in the view model. However I imagine one should be able to send the entire source item. However when I send anything other than a string either the app crashes or the buttons are all disabled and don't seem to trigger the command. This OOP and xamarin newb would very much appreciate any pointers/help. I suspect it is just the syntax in the button, or in the command that I don't understand, what I have at the moment is:</p>
  <pre><code>&lt;ContentPage.BindingContext&gt;
      &lt;local:TestViewModel/&gt;
  &lt;/ContentPage.BindingContext&gt;
  &lt;ContentPage.Content&gt;
      &lt;StackLayout  &gt;
          &lt;Label Text=&quot;{Binding SelectedItem.Term_id}&quot;
              VerticalOptions=&quot;CenterAndExpand&quot; 
              HorizontalOptions=&quot;CenterAndExpand&quot; /&gt;
          &lt;BoxView HeightRequest=&quot;1&quot; BackgroundColor=&quot;Black&quot; HorizontalOptions=&quot;FillAndExpand&quot; /&gt;
          &lt;ListView x:Name=&quot;propListView&quot;
              SelectedItem=&quot;{Binding SelectedItem}&quot;
              ItemsSource=&quot;{Binding SimpleProperties}&quot;  &gt;
              &lt;ListView.ItemTemplate&gt;
                  &lt;DataTemplate&gt;
                      &lt;ViewCell x:Name=&quot;theItem&quot; &gt;
                          &lt;StackLayout Orientation=&quot;Horizontal&quot;&gt;
                              &lt;Button Text=&quot;{Binding Agt_name}&quot;
                                Command=&quot;{Binding BindingContext.doCheckin, Source={x:Reference Page}}&quot;
                                CommandParameter=&quot;{Binding BindingContext.doCheckin, Source={x:Reference theItem}, Mode=OneWayToSource}&quot;
                                      /&gt;
                              &lt;Label Text=&quot;{Binding MilesDistance, StringFormat='~{0:f2} mi.'},
                          Converter={ConvertToDouble}}&quot; HorizontalOptions=&quot;CenterAndExpand&quot; /&gt;
                          &lt;/StackLayout&gt;
                      &lt;/ViewCell&gt;
                  &lt;/DataTemplate&gt;
              &lt;/ListView.ItemTemplate&gt;
          &lt;/ListView&gt;
      &lt;/StackLayout&gt;
  &lt;/ContentPage.Content&gt;
  </code></pre>
  <p>...</p>
  <pre><code>using AgentApp.Models;
  using System;
  using System.Collections.Generic;
  using System.Collections.ObjectModel;
  using System.Windows.Input;
  using Xamarin.Forms;
  
  namespace AgentApp
  {
      class TestViewModel : BaseViewModel
      {
          private ObservableCollection&lt;Property&gt; simpleProperties;
          public ObservableCollection&lt;Property&gt; SimpleProperties { set { SetProperty(ref simpleProperties, value); } get { return simpleProperties; } }
  
          private Property selectedItem;
          public Property SelectedItem { get { return selectedItem; } set { SetProperty(ref selectedItem, value); } }
  
          public ICommand setSelection { private set; get; }
          public ICommand doCheckin { private set; get; }
          public TestViewModel()
          {
              var SimplePropertiesList = new List&lt;Property&gt;();
              for (int i = 1; i &lt;= 5; i++)
              {
                  Property prop = new Property();
                  prop.Term_id = i.ToString();
                  prop.Agt_name = &quot;Prop &quot; + i.ToString();
                  prop.MilesDistance = (double)i * 2.5;
                  SimplePropertiesList.Add(prop);
              }
              SimpleProperties = new ObservableCollection&lt;Property&gt;(SimplePropertiesList);
  
              /* for buttons:*/
              doCheckin = new Command&lt;Property&gt;(
                  execute: (Property item) =&gt;
                  {
                      Console.WriteLine(&quot;doCheckin() executes: &quot; + item.Term_id);
                      SelectedItem = item;
                  },
              canExecute: (Property item) =&gt;
              {
                  Console.WriteLine(&quot;doCheckin() canExecute return&quot; + item.Term_id);
                  return (SelectedItem != item); 
              }
                  );
          }
      }
  }
  </code></pre>
  <p>and of course</p>
  <pre><code>class BaseViewModel : INotifyPropertyChanged
      {
          public bool SetProperty&lt;T&gt;(ref T storage, T value, [CallerMemberName] string propertyName = null)
          {
              if (Object.Equals(storage, value)) return false;
              storage = value;
              OnPropertyChanged(propertyName);
              return true;
          }
          public virtual void OnPropertyChanged(string propertyName)
          {
              PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
          }
          public event PropertyChangedEventHandler PropertyChanged;
      }
  </code></pre>
  <p>Thanks in advance!</p>