maui
maui copied to clipboard
Changing visibility on an SwipeItem causes multiple items to be executed
Description
Let's say you have a to do list. There are two swipe commands for each item:
- One for setting the item to completed.
- Another to set to not completed.
Only one option is visible at the time. If you execute the first swipe item, then the second one will become visible and then this is executed as well.
Steps to Reproduce
- Create a new MAUI app.
- Change MainPage.xaml to:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:v="clr-namespace:MauiIssues"
x:Class="MauiIssues.MainPage"
>
<Grid>
<CollectionView ItemsSource="{Binding Issues}">
<CollectionView.ItemTemplate>
<DataTemplate>
<SwipeView Threshold="250">
<SwipeView.LeftItems>
<SwipeItems Mode="Execute">
<SwipeItem Text="Set as not completed"
IsVisible="{Binding IsCompleted}"
Command="{Binding CommandToggle}"
BackgroundColor="Red" />
<SwipeItem Text="Set as completed"
IsVisible="{Binding IsNotCompleted}"
Command="{Binding CommandToggle}"
BackgroundColor="Green" />
</SwipeItems>
</SwipeView.LeftItems>
<HorizontalStackLayout Spacing="20">
<Label Text="{Binding Title, Mode=OneWay}" />
<Label Text="Completed: " />
<Label Text="{Binding IsCompleted}" />
</HorizontalStackLayout>
</SwipeView>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</Grid>
</ContentPage>
- Change MainPage.cs to:
using System.Collections.ObjectModel;
using System.Windows.Input;
namespace MauiIssues;
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
BindingContext = this;
}
public class Issue : BindableObject
{
public string Title { get; set; }
public bool IsCompleted { get; set; } = true;
public bool IsNotCompleted => !IsCompleted;
public ICommand CommandToggle { get; }
public Issue()
{
CommandToggle = new Command(() => Toggle());
}
public void Toggle()
{
IsCompleted = !IsCompleted;
System.Diagnostics.Debug.WriteLine($"{DateTime.Now.ToString("HH:mm:ss")} Setting {Title} to {IsCompleted}");
OnPropertyChanged(nameof(IsCompleted));
OnPropertyChanged(nameof(IsNotCompleted));
}
}
public ObservableCollection<Issue> Issues { get; } = new ObservableCollection<Issue>();
protected override void OnAppearing()
{
base.OnAppearing();
Issues.Add(new Issue { Title = "Issue 1", IsCompleted = false });
Issues.Add(new Issue { Title = "Issue 2", IsCompleted = true });
Issues.Add(new Issue { Title = "Issue 3", IsCompleted = false });
Issues.Add(new Issue { Title = "Issue 4", IsCompleted = true });
}
}
- Run the application on Android (swipe doesn't work on Windows).
- Swipe first item to set it to completed. This will work.
- Swipe second item to set it not completed. This will happen, but immediately it will also be set to completed. You can see this in the logs.
Full sample: https://github.com/pekspro/MauiIssues/tree/7580_Changing_visibility_on_SwipeItem_multiple_execution
Version with bug
6.0 (current)
Last version that worked well
Unknown/Other
Affected platforms
Android, I was not able test on other platforms
Affected platform versions
Android 11
Did you find any workaround?
In the mentioned scenario, just use one command, and use converters to change to content. But I guess there are other cases where this is not possible.
Relevant log output
No response
Another possible workaround is to move OnPropertyChanged lines to an event handler attached to SwipeEnded event.
verified repro with above repro project on windows, swipe doesn't work. repro project: MauiIssues.zip on android:
- set it to completed. this can work
- set to not completed, the event
Toggleis executed twice, first is set to false, and immediately it is set to true.
"swipe doesn't work on Windows"
Are you using a touch screen?.
"swipe doesn't work on Windows"
Are you using a touch screen?.
I meant that touch events doesn't work with mouse in Windows :-) That's another issue :-)
We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.
I've updated sample application to .NET 7. The same issue remains.
Verified this on Visual Studio Enterprise 17.6.0 Preview 7.0. Repro on Android 13.0 with below Project: 7580.zip
Swipe second item to set it not completed. It will execute twice.
SwipeView 本身就是用于触碰而设计的吧。