Using IsDescructive in ContextAction produces non clickable items on iOS

Hello,
I have a listview with uneven rows. The items have a typical context action "delete" with the attribute "IsDescructive="true". Now, when I swipe on an item to open the context menu and then cancel the action, the item is not clickable anymore until the listview is realoaded completely.

This is XAML code of my listview:

<ListView x:Name="listView" Margin="0,0,0,0" HasUnevenRows="True" SelectionMode="None" ItemTapped="ListView_ItemTapped" ItemAppearing="ListView_ItemAppearing" BackgroundColor="{StaticResource StandardBackgroundColor}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <ViewCell.ContextActions>
                    <MenuItem Clicked="OnDelete" CommandParameter="{Binding .}" Text="Löschen"  />
                </ViewCell.ContextActions>
                <StackLayout Orientation="Vertical" HeightRequest="90" HorizontalOptions="Fill">
                    <StackLayout Orientation="Horizontal" Margin="10,10,10,0" HorizontalOptions="Fill">
                        <Label Text="{Binding Discipline}" VerticalOptions="Center" HorizontalOptions="StartAndExpand" FontSize="Small" FontAttributes="Bold" TextColor="Black" MaxLines="1"/>
                        <Label Text="{Binding Startdate}" VerticalOptions="Center" HorizontalOptions="End" FontSize="Small" MinimumWidthRequest="100" HorizontalTextAlignment="End" MaxLines="1"/>
                    </StackLayout>
                    <StackLayout Orientation="Horizontal" Margin="10,0,10,0" HorizontalOptions="Fill" >
                        <Label Text="{Binding FinalResult}" VerticalOptions="Center" HorizontalOptions="Start" WidthRequest="50" MinimumWidthRequest="50" FontSize="Medium" TextColor="{StaticResource ColorPrimary}" FontAttributes="Bold"/>
                        <Label Text="{Binding PartResults}" VerticalOptions="Center" HorizontalOptions="StartAndExpand" FontSize="Small"/>
                    </StackLayout>
                    <StackLayout Orientation="Horizontal" Margin="10,0,10,10" HorizontalOptions="Fill">
                        <Label Text="{Binding ActivityType}" VerticalOptions="Center" HorizontalOptions="Start" FontSize="Small" TextColor="Gray" FontAttributes="Bold"/>
                    </StackLayout>
                </StackLayout>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

In the ItemAppearing event I load the model from the database to set the labels via the viewmodel.
The listview ItemSource is set in the constructor of the page and the type is ObservableCollection. So not something special.

As soon as I remove the IsDestructive attribute from the MenuItem, everything works well.

Does someone also have the problem?

Answers

  • LandLuLandLu Member, Xamarin Team Xamurai

    I can reproduce this issue, we will escalate it to the product team. You can also raise an issue on the github: https://github.com/xamarin/Xamarin.Forms.
    For now, I will give you an alternative workaround: You could bind your root StackLayout's tap gesture to your code behind. This tap command will be always fired when a user clicks the cell.
    Here is my view model:

    public class MainPageViewModel : INotifyPropertyChanged
    {
        MainPageModel selectedModel;
        public MainPageModel SelectedModel
        {
            set
            {
                selectedModel = value;
                onPropertyChanged();
            }
            get
            {
                return selectedModel;
            }
        }
    
        List<MainPageModel> itemsSoruce;
        public List<MainPageModel> ItemsSource
        {
            set
            {
                itemsSoruce = value;
                onPropertyChanged();
            }
            get
            {
                return itemsSoruce;
            }
        }
    
        public ICommand BtnClick { set; get; }
    
        public MainPageViewModel()
        {
            List< MainPageModel> list = new List<MainPageModel>();
            for (int i=0; i<10; i++)
            {
                list.Add(new MainPageModel { Title = "Item" + i, ViewModel = this });
            }
            ItemsSource = list;
    
            BtnClick = new Command(() =>
            {
                SelectedModel = list[4];
            });
        }
    
    
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        void onPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    
    
    public class MainPageModel : INotifyPropertyChanged
    {
        string title;
        public string Title {
            set
            {
                title = value;
                onPropertyChanged();
            }
            get
            {
                return title;
            }
        }
        public ICommand TapCommand { set; get; }
    
    
        public MainPageViewModel ViewModel { set; get; }
        public MainPageModel()
        {
            TapCommand = new Command((parameter) =>
            {
                this.ViewModel.SelectedModel = parameter as MainPageModel;
                // ... Do something here
            });
        }
    
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        void onPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    

    Xaml:

    <ListView ItemsSource="{Binding ItemsSource}" SelectedItem="{Binding SelectedModel, Mode=TwoWay}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <ViewCell.ContextActions>
                        <MenuItem Text="Delete" IsDestructive="True"/>
                    </ViewCell.ContextActions>
    
                    <StackLayout>
                        <StackLayout.GestureRecognizers>
                            <TapGestureRecognizer Command="{Binding TapCommand}" CommandParameter="{Binding}"/>
                        </StackLayout.GestureRecognizers>
                        <Label Text="{Binding Title}"/>
                    </StackLayout>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
    

    I also attached my project here. You can run it on your side to see the effect.

  • SchulleberndSchullebernd Member ✭✭
    Thanks for the answer. Thats a good workaround. Will try this these days. This is better than evertime reloading the datasource.

    I posted the issue into github:
    https://github.com/xamarin/Xamarin.Forms/issues/5130
    Lets see and wait what happens.
Sign In or Register to comment.