Handling Child Control Event in Listview using XAMARIN.FORMS

We can add child controls to Listview in Xamarin.Forms. In order to see the child control in action we will take an example. Let’s display a list of data in the Listview and perform delete option on the list data per row basis.

Since we need to add multiple columns in the list view, we need to use the DataTemplate to define the custom view. Let’s use a model class to assign the data to the custom view.

  1. public class Item  
  2. {  
  3.    public string ItemName { getset; }  
  4.    public string ItemDetails { getset; }  
  5. }  
We will use XAML to design a Listview

InsideXAMLView

In the above XAML, we have used the StackLayout as the parent container for the child views. It contains a Label and a Listview. UI Control is ready.

Time to add event to the child control

We will replace the Button control in the above XAML with the following line
  1. <Button Text="Delete" CommandParameter="{Binding ItemName}" Clicked="DeleteClicked"></Button>  
With this new line we have added the Clicked Event handler to theButton control and also a CommandParameter in order to locate the item at runtime.

How the final XAML look like then ?

  1. <?xml version="1.0" encoding="utf-8" ?>  
  2. <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"   
  3. x:Class="RelativeLayout.CustomerForm">  
  4.    <StackLayout>  
  5.       <Label x:Name="lbl1" Text="Items" VerticalOptions="StartAndExpand" HorizontalOptions="Center"></Label>  
  6.       <ListView x:Name="lstItems" VerticalOptions="FillAndExpand">  
  7.          <ListView.ItemTemplate>  
  8.             <DataTemplate>  
  9.                <ViewCell>  
  10.                   <ViewCell.View>  
  11.                      <StackLayout Orientation="Horizontal">  
  12.                         <Label Text="{Binding ItemName}" HorizontalOptions="StartAndExpand" FontSize="30"></Label>  
  13.                         <Button Text="Delete" CommandParameter="{Binding ItemName}" Clicked="DeleteClicked">        
  14.                         </Button>  
  15.                      </StackLayout>  
  16.                   </ViewCell.View>  
  17.                </ViewCell>  
  18.             </DataTemplate>  
  19.          </ListView.ItemTemplate>  
  20.       </ListView>  
  21.    </StackLayout>  
  22. </ContentPage>  
Code behind for this XAML
  1. public partial class CustomerForm : ContentPage  
  2. {  
  3.    public List<Item> allItems;  
  4.    
  5.    
  6.    public CustomerForm()  
  7.    {  
  8.       allItems = new List<Item>  
  9.       {  
  10.          new Item(){ItemName = "Rice", ItemDetails = "Rich in carbohydrates"},  
  11.          new Item(){ItemName = "Dal", ItemDetails = "Rich in protine"},  
  12.          new Item(){ItemName = "Milk", ItemDetails = "Rich in protine"},  
  13.       };  
  14.       InitializeComponent();  
  15.       lstItems.ItemsSource = allItems;  
  16.    }  
  17.    
  18.    
  19.    public void DeleteClicked(object sender, EventArgs e)  
  20.    {  
  21.       var item = (Xamarin.Forms.Button)sender;  
  22.       Item listitem = (from itm in allItems where itm.ItemName == item.CommandParameter.ToString() select  
  23.                         itm).FirstOrDefault<Item>();  
  24.       allItems.Remove(listitem);  
  25.    }  
  26. }  
Running the app

Running fine. OOOPSSSSSSS… but the deletion is not working. That’s correct. Because, the item is getting deleted from the collection but the ItemSource is not getting refreshed.

What we need to do then ?????
Pretty simple. Let’s use an ObservableCollection to assign theItemSource.

Modifying the Model Class

  1. public class Item  
  2. {  
  3.       public string ItemName { getset; }  
  4.       public string ItemDetails { getset; }  
  5. }  
  6.    
  7. public class ItemList : INotifyPropertyChanged  
  8. {  
  9.       public event PropertyChangedEventHandler PropertyChanged;  
  10.       public ObservableCollection<Item> _items;  
  11.    
  12.       public ObservableCollection<Item> Items  
  13.       {  
  14.          get { return _items; }  
  15.          set { _items = value; OnPropertyChanged("Items"); }  
  16.       }  
  17.    
  18.       protected virtual void OnPropertyChanged(string propertyName)  
  19.       {  
  20.          if (PropertyChanged == null)  
  21.          return;  
  22.          PropertyChanged(thisnew PropertyChangedEventArgs(propertyName));  
  23.       }  
  24.    
  25.       public ItemList(List<Item> itemList)  
  26.       {  
  27.          Items = new ObservableCollection<Item>();  
  28.          foreach (Item itm in itemList)  
  29.          {  
  30.             Items.Add(itm);  
  31.          }  
  32.       }  
  33. }  
Added a new ObservableCollection class which will be used as theItemSource of the Listview.

Small changes in the code behind

  1. public partial class CustomerForm : ContentPage  
  2. {  
  3.    public List<Item> allItems;  
  4.    ItemList items;  
  5.    
  6.    public CustomerForm()  
  7.    {  
  8.       allItems = new List<Item>  
  9.       {  
  10.          new Item(){ItemName = "Rice", ItemDetails = "Rich in carbohydrates"},  
  11.          new Item(){ItemName = "Dal", ItemDetails = "Rich in protine"},  
  12.          new Item(){ItemName = "Milk", ItemDetails = "Rich in protine"},  
  13.       };  
  14.       InitializeComponent();  
  15.       items = new ItemList(allItems);  
  16.       lstItems.ItemsSource = items.Items;  
  17.    }  
  18.    
  19.    
  20.    public void DeleteClicked(object sender, EventArgs e)  
  21.    {  
  22.       var item = (Xamarin.Forms.Button)sender;  
  23.       Item listitem = (from itm in items.Items where itm.ItemName == item.CommandParameter.ToString() select                   itm).FirstOrDefault<Item>();  
  24.       items.Items.Remove(listitem);  
  25.    }  
  26. }  
We have modified the code and added the ObservableCollectionobject in the ItemSource. So that the delete operation gets reflected in the Listview.

How is the output ?

Now, we can see the immediate effect of Delete button as soon as we click it.

ListviewOutput

Happy coding