I'm having a problem with the list view context action (delete) on a UWP project. I have no idea of the same issues apply on iOS or Android.
1) If you add three items to a list, use the context action to delete one of them, then add another new item to the list, then you cannot delete the third item on the list any longer even tho the context menu appears. The context action command parameter references the previously deleted item even tho it no longer exists in the datasource. You can delete any of the other items, but then you get a similar unable to delete issue with any other new ones that you add.
2) If the list view's viewcell is a stack layout of horizontal labels, swiping on whitespace between labels does not display the context menu. Using a Grid behaves as expected.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Views.TestPage2">
<StackLayout>
<Button Text="Button" Command="{Binding ButtonCommand}" />
<Label Text="{Binding Counter}"/>
<ListView x:Name="ItemsListView" ItemsSource="{Binding DataSource}"
HorizontalOptions = "LayoutOptions.FillAndExpand"
VerticalOptions = "LayoutOptions.FillAndExpand">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.ContextActions>
<MenuItem Clicked="OnDelete" CommandParameter="{Binding .}" Text="Delete" IsDestructive="True" />
</ViewCell.ContextActions>
<StackLayout Orientation="Horizontal" Padding="10,0,10,0">
<Label Text="{Binding Title}" FontSize="Medium" HorizontalOptions="StartAndExpand"/>
<Label Text="{Binding Quantity}" FontSize="Medium" HorizontalOptions="EndAndExpand"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace Views
{
public partial class TestPage2 : ContentPage
{
public TestPage2()
{
InitializeComponent();
var model = new TestListViewModel();
this.BindingContext = model;
}
public void OnDelete(object sender, EventArgs e)
{
var mi = ((MenuItem)sender);
((TestListViewModel)this.BindingContext).RemoveItem((TestListViewDataItem)mi.CommandParameter);
}
}
public class TestListViewModel : INotifyPropertyChanged
{
public TestListViewModel()
{
DataSource = new ObservableCollection<Views.TestListViewDataItem>();
ButtonCommand = new Command(() =>
{
Counter++;
DataSource.Add(new Views.TestListViewDataItem(string.Format("item : {0}", Counter), 0));
});
}
public void RemoveItem(TestListViewDataItem item)
{
DataSource.Remove(item);
}
public Command ButtonCommand { get; set; }
public ObservableCollection<TestListViewDataItem> DataSource { get; set; }
public TestListViewDataItem SelectedItem { get; set; }
public int Counter { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string PropertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(PropertyName));
}
}
public class TestListViewDataItem
{
public TestListViewDataItem(string title, int quantity)
{
Title = title;
Quantity = quantity;
}
public string Title { get; set; }
public int Quantity { get; set; }
}
}