Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SwipeView throw exception on windows #8870

Open
1 task done
hujun-open opened this issue Jul 20, 2022 · 31 comments
Open
1 task done

SwipeView throw exception on windows #8870

hujun-open opened this issue Jul 20, 2022 · 31 comments
Assignees
Labels
area-controls-swipeview SwipeView external partner/winui WinUI / Project Reunion platform/windows 🪟 t/bug Something isn't working
Milestone

Comments

@hujun-open
Copy link

hujun-open commented Jul 20, 2022

Description

it seems following combintions triggers program to throw an exception of "Value does not fall within the expected range.":

  • CollectioView with SwipeView
  • the binding list of collectionview is initiazed with some items
  • then clear the list, and add a new item

I have created a simple example to reproduce: https://github.com/hujun-open/mauiswieviewissue

I only found this issue on windows, android works fine.

following are the visual studio version info:

Microsoft Visual Studio Community 2022
Version 17.3.0 Preview 4.0
VisualStudio.17.Preview/17.3.0-pre.4.0+32714.290
Microsoft .NET Framework
Version 4.8.04084

Installed Version: Community

ASP.NET and Web Tools   17.3.372.35679
ASP.NET and Web Tools

Azure App Service Tools v3.0.0   17.3.372.35679
Azure App Service Tools v3.0.0

C# Tools   4.3.0-3.22329.30+29e657c0582904529bae2a87c227220e03f509cf
C# components used in the IDE. Depending on your project type and settings, a different version of the compiler may be used.

Common Azure Tools   1.10
Provides common services for use by Azure Mobile Services and Microsoft Azure Tools.

Extensibility Message Bus   1.2.6 (master@34d6af2)
Provides common messaging-based MEF services for loosely coupled Visual Studio extension components communication and integration.

Microsoft JVM Debugger   1.0
Provides support for connecting the Visual Studio debugger to JDWP compatible Java Virtual Machines

Mono Debugging for Visual Studio   17.3.20 (3f4cb00)
Support for debugging Mono processes with Visual Studio.

NuGet Package Manager   6.3.0
NuGet Package Manager in Visual Studio. For more information about NuGet, visit https://docs.nuget.org/

Razor (ASP.NET Core)   17.0.0.2232702+e1d654e792aa2fe6646a6935bcca80ff0aff4387
Provides languages services for ASP.NET Core Razor.

TypeScript Tools   17.0.10701.2001
TypeScript Tools for Microsoft Visual Studio

Visual Basic Tools   4.3.0-3.22329.30+29e657c0582904529bae2a87c227220e03f509cf
Visual Basic components used in the IDE. Depending on your project type and settings, a different version of the compiler may be used.

Visual F# Tools   17.1.0-beta.22327.2+ddc90b20287a765a9d526da42b3be0dd8e907ec5
Microsoft Visual F# Tools

Visual Studio IntelliCode   2.2
AI-assisted development for Visual Studio.

VisualStudio.DeviceLog   1.0
Information about my package

VisualStudio.Mac   1.0
Mac Extension for Visual Studio

VSPackage Extension   1.0
VSPackage Visual Studio Extension Detailed Info

Xamarin   17.3.0.288 (main@5d42bb2)
Visual Studio extension to enable development for Xamarin.iOS and Xamarin.Android.

Xamarin Designer   17.3.0.204 (remotes/origin/d17-3@f5da0100a)
Visual Studio extension to enable Xamarin Designer tools in Visual Studio.

Xamarin.Android SDK   13.0.0.0 (d17-3/030cd63)
Xamarin.Android Reference Assemblies and MSBuild support.
    Mono: dffa5ab
    Java.Interop: xamarin/java.interop/d17-3@7716ae53
    SQLite: xamarin/sqlite/3.38.5@df4deab
    Xamarin.Android Tools: xamarin/xamarin-android-tools/main@14076a6

Steps to Reproduce

see readme @ https://github.com/hujun-open/mauiswieviewissue

Version with bug

6.0.400

Last version that worked well

Unknown/Other

Affected platforms

Windows

Affected platform versions

windows 10 Enterprise 21H2, OS build 19044.1826

Did you find any workaround?

no

Relevant log output

+		sender	{SwipeIssueDemo.WinUI.App}	object {SwipeIssueDemo.WinUI.App}
-		e	{Microsoft.UI.Xaml.UnhandledExceptionEventArgs}	Microsoft.UI.Xaml.UnhandledExceptionEventArgs
-		Exception	{"Value does not fall within the expected range."}	System.Exception {System.ArgumentException}
+		Data	{System.Collections.ListDictionaryInternal}	System.Collections.IDictionary {System.Collections.ListDictionaryInternal}
		HResult	-2147024809	int
		HelpLink	null	string
+		InnerException	null	System.Exception
		Message	"Value does not fall within the expected range."	string
		ParamName	null	string
		Source	null	string
		StackTrace	null	string
		TargetSite	null	System.Reflection.MethodBase
+		Static members		
+		Non-Public members		
		Handled	false	bool
		Message	"The parameter is incorrect.\r\n"	string
+		Non-Public members

Depends on

VS bug #1870771

@hujun-open hujun-open added s/needs-verification Indicates that this issue needs initial verification before further triage will happen t/bug Something isn't working labels Jul 20, 2022
@jsuarezruiz jsuarezruiz self-assigned this Jul 21, 2022
@samhouts samhouts added p/1 Work that is important, and has been scheduled for release in this or an upcoming sprint and removed p/1 Work that is important, and has been scheduled for release in this or an upcoming sprint labels Jul 21, 2022
@rmarinho rmarinho added s/triaged Issue has been reviewed platform/windows 🪟 and removed s/needs-verification Indicates that this issue needs initial verification before further triage will happen labels Jul 21, 2022
@jsuarezruiz
Copy link
Contributor

The native exception from WinUI:

onecoreuap\windows\dwm\dcomp\winrtnested\wrtcompositioninteractionsource.cpp(109)\dcompi.dll!00007FF806E93531: (caller: 00007FF806E9676F) ReturnHr(1) tid(6684) 80070057 The parameter is incorrect.
    Msg:[PointerEventRouter (Interaction) object already has an owner.] 

@hartez hartez removed the fatal label Aug 1, 2022
@GuildOfCalamity
Copy link

I'm seeing a similar issue in my simple MAUI application with an ObservableCollection inside a CollectionView. I can add items, but once I remove an item and then try to add another item I get the UnhandledException:
[Microsoft.UI.Xaml.UnhandledExceptionEventArgs] Exception = {"Value does not fall within the expected range."} Message = {"The parameter is incorrect."}
I also have defensive code in each add/remove method to make sure the collection is not null and the item has content before removing or adding.

@GuildOfCalamity
Copy link

GuildOfCalamity commented Aug 18, 2022

[UPDATE]
I just discovered the issue was with the SwipeView inside the CollectionView. I hope someone on the MAUI team is working on the bugs with the SwipeView control.
I have taken it out for now; not sure how a developer would make this work on a phone?... for now I'm just going to show a delete button.

<CollectionView
     Grid.Row="2"
     Grid.ColumnSpan="2"
     ItemsSource="{Binding Items}"
     SelectionMode="None">
     <CollectionView.ItemTemplate>
         <DataTemplate x:DataType="{x:Type x:String}">
             <!-- [I had to remove the SwipeView because of it's buggyness and the UnhandledException: "Value does not fall within the expected range."]
             <SwipeView>
                 <SwipeView.RightItems>
                     <SwipeItems>
                         <SwipeItem
                             BackgroundColor="Red"
                             Command="{Binding Source={RelativeSource AncestorType={x:Type viewmodel:MainViewModel}}, Path=DeleteCommand}"
                             CommandParameter="{Binding .}"
                             Text="Delete" />
                     </SwipeItems>
                 </SwipeView.RightItems>
             -->
             <Grid Padding="0,5" ColumnDefinitions=".9*, .1*">
                 <Frame Grid.Column="0" HasShadow="True">
                     <Label
                         Grid.Row="0"
                         Margin="0"
                         Padding="0"
                         FontSize="24"
                         Text="{Binding .}"
                         VerticalOptions="Start" />
                 </Frame>
                 <Button
                     Grid.Column="1"
                     Margin="3,0,0,0"
                     Padding="24"
                     BackgroundColor="Transparent"
                     Command="{Binding Source={RelativeSource AncestorType={x:Type viewmodel:MainViewModel}}, Path=DeleteCommand}"
                     CommandParameter="{Binding .}" />
             </Grid>
             <!--
             </SwipeView>
             -->
         </DataTemplate>
     </CollectionView.ItemTemplate>
 </CollectionView>

The binding source "Items" is an ObservableCollection{string} inside the ViewModel.
You can uncomment the SwipeView to see the exception happen.

@codemonkey85
Copy link

Are there any recommended workarounds for this? There's no conditional compilation in XAML, so the only other thing I can think of is having a separate page / view for Windows vs other platforms.

@prom3theu5
Copy link

Thats what I have had to do for now
Separate shells for windows vs everything else.

@agustinbcu01
Copy link

The issue is possible to reproduce using a Delete Button

///ViewModels.cs

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Windows.Input;

namespace Inventory.ViewModels
{

    public partial class MainViewModel : ObservableObject
    {
        public MainViewModel() {
            items = new ObservableCollection<string>();
            text = string.Empty;
        }
        [ObservableProperty]
        ObservableCollection<string> items;

        [ObservableProperty]
        string text;

        [RelayCommand]
        void Add() {
            if (string.IsNullOrEmpty(text?.Trim()))
            {
                return;
            }
            Items.Add(text);
            Text = string.Empty;
        }


        [RelayCommand]
        void Delete(string value)
        {
            if (string.IsNullOrEmpty(value?.Trim()))
            {
                return;
            }
            if (Items.Any(s => s.Equals(value)))
            {
                Items.Remove(value);
            }
        }

    }

    
}
//MainPage.xaml
<?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"
             x:Class="Inventory.MainPage"
             xmlns:viewmodel="clr-namespace:Inventory.ViewModels"
             x:DataType="viewmodel:MainViewModel">
    <Grid RowDefinitions="100, auto, *" ColumnDefinitions=".75*, .25*" Padding="10" RowSpacing="10" ColumnSpacing="10">
        <Image Grid.ColumnSpan="2" Source="dotnet_bot.png" BackgroundColor="Orange"></Image>
        <Entry Placeholder="Enter the task Nanme" Grid.Row="1" Text="{Binding Text}"></Entry>
        <Button Text="Add" Grid.Row="1" Grid.Column="1" Command="{Binding AddCommand}"></Button>
        <CollectionView Grid.Row="2" Grid.ColumnSpan="2" ItemsSource="{Binding Items}">
            
            <CollectionView.ItemTemplate>
                <DataTemplate x:DataType="{x:Type x:String}">
                    <SwipeView>
                        <SwipeView.RightItems>
                            <SwipeItems>
                                <SwipeItem Text="Delete" BackgroundColor="Red"></SwipeItem>
                            </SwipeItems>
                        </SwipeView.RightItems>
                        <Grid  RowDefinitions="auto" ColumnDefinitions="*, auto">
                        <Frame BackgroundColor="Navy">
                            <Label Text="{Binding .}" FontSize="24" Grid.Column="1"></Label>
                               
                            </Frame>
                            <Button Text="Delete" BackgroundColor="Red" Grid.Column="2" 
                                    Command="{Binding Source={RelativeSource AncestorType={x:Type viewmodel:MainViewModel}}, Path=DeleteCommand}" 
                                    CommandParameter="{Binding .}"/>
                        </Grid>
                    </SwipeView>

                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>        
    </Grid>

</ContentPage>
//MainPage 
public partial class MainPage : ContentPage
{
	public MainPage( MainViewModel vm)
	{
		InitializeComponent();
		BindingContext = vm;
	}

	
}

//MauiProgram.cs

using Inventory.ViewModels;

namespace Inventory;

public static class MauiProgram
{
	public static MauiApp CreateMauiApp()
	{
		var builder = MauiApp.CreateBuilder();
		builder
			.UseMauiApp<App>()
			.ConfigureFonts(fonts =>
			{
				fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
				fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
			});
		builder.Services.AddSingleton<MainPage>();
        builder.Services.AddSingleton<MainViewModel>();



        return builder.Build();
	}
}



@jbe2277
Copy link

jbe2277 commented Sep 28, 2022

UPDATE 2: I still have the issue with VS 2022 17.4.5.

UPDATE: My issue seems to be fixed with VS 2022 17.3.6.


I get the same exception now on Windows.

It worked with VS 2022 17.3.2.
After upgrading to VS 2022 17.3.5 this issue occurred in my App as well on Windows. But it works on Android 12.

Reproduce:

  1. Clone: https://github.com/jbe2277/waf/tree/904ae96984603d982eaa85bd6a411bc89717bbac
  2. Open src\NewsReader\NewsReader.sln

Try out:

@mattleibow mattleibow added the s/needs-info Issue needs more info from the author label Nov 10, 2022
@ghost
Copy link

ghost commented Nov 10, 2022

Hi @hujun-open. We have added the "s/needs-info" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.

@mattleibow
Copy link
Member

Is this fixed? Can we close?

@david-maw
Copy link

@mattleibow I'm curious, how @hujun-open would be expected to know if it is fixed, is the merged PR available somewhere? I submitted issue #9423 which was closed as a duplicate of this issue, as well as #9233 which is probably fixed by the same PR, so I'd like a fix too but I'm not sure how to go about discovering if this is it until the PR changes are released. Did you have some mechanism in mind?

@ghost ghost added s/needs-attention Issue has more information and needs another look and removed s/needs-info Issue needs more info from the author labels Nov 10, 2022
@codemonkey85
Copy link

I ran into this issue about two days ago, right after upgrading to .NET 7 release. So it's definitely unsolved.

@Eilon Eilon added the legacy-area-controls Label, Button, CheckBox, Slider, Stepper, Switch, Picker, Entry, Editor label Jun 20, 2023
@samhouts samhouts modified the milestones: .NET 8, .NET 8 GA Jul 12, 2023
@KeithBoynton
Copy link

I'm using .net8 preview 5 and the problem still exists for me, my project is using windows and mac desktop, and iOS and Android. Working fine in all but Windows where it crashes because I have a swipe view inside a collection view.

Is this being worked on for .net8 ?

@david-maw
Copy link

Absent a response from Microsoft I can only guess, but it looks like it's being worked on. I noticed a while back that PR #11229 by @jsuarezruiz seems like it corrects this but says "The PR require some changes in the public API. Will maintain the changes up to date but need to wait to .NET 8." That was in November of 2022, however it looks like a new decision has been reached and PR #11229 was closed at the beginning of July 2023 with "We are going to close this PR focusing on fix crashes or any problem that prevents the use of SwipeView in Windows while we continue to promote the implementations and accessibility on the desktop (keyboard support etc)."

A SwipeView without mouse support is not a very practical desktop UI element but as long as its presence does not crash the app (as it currently does in this example) it shouldn't be too hard to code around that and offer an alternative desktop interface. Not hard, but tedious.

@KeithBoynton
Copy link

I agree, I have a swipe view for use on mobile devices and am using context menus for desktop. At a minimum we need the presence of a swipe view in a collection view to at least not crash!

@jsuarezruiz
Copy link
Contributor

Could be related with: microsoft/microsoft-ui-xaml#2527

Can reproduce the issue even with the changes:

  • SwipeControl without SwipeItems.
  • SwipeControl wrapped by a Container.
  • Setting default initial size, delay measuring etc.

@samhouts samhouts added external partner/winui WinUI / Project Reunion labels Aug 15, 2023
@Rabidgoalie
Copy link

I don't know if this will help the majority of projects encountering this problem, but I have found an All-XAML workaround to this problem. This should work with any control that uses a DataTemplate, but, as I am fairly new to .NET MAUI / Xamarin, I don't know how far this workaround will extend to everyone's issues. I do hope that this helps someone, though.

I have broken this long post into two parts, the background for my issue (in case some of you are facing something similar, or where this information may be useful to someone). And, a second section called 'The Good Stuff'. If you just want to see the solution that I used, skip the first section (it may be a waste of your time to read it anyway). 😃

Background for My Issue

I was encountering this issue when I deleted an item in my ViewModel's ObservableCollection (which is bound to a CollectionView in my main view's XAML) and then added a new item during the same session. On Windows it would crash the application, but it worked fine on Android (I didn't test it on iOS or MacOS). This crash occurred during the Shell.Current.GoToAsync() method, which I am using to pass an object back to the main view's VM, using the ApplyQueryAttributes() method to capture the passed in data. All of the application's data is being stored to a SQLite database, which was important to me in figuring out that it wasn't just a null value of some sort causing a crash.

Execution would follow as one would expect, by entering the command I have defined to create the data object (when the 'Create' button is pressed) and call Shell.Current.GoToAsync() to go back to the main view, passing the data object. The data object is valid; my immediate thought was that somehow it may be null when I encountered the error, but it contained all the necessary data. The execution then jumped from GoToAsync() to the VM's ApplyQueryAttributes() method where it correctly processed the data object by adding it to my ObservableCollection and storing it in the database. Good, no issues. This is where things seem strange to me, because then execution jumped back to the GoToAsync() method again, even though I have await-ed the GoToAsync() method. And this point in the execution is where the application would crash. To be clear, the data object is added to the ObservableCollection and to the database successfully. After the crash, I can start the app up again and the added object (which caused the crash) will be in the CollectionView...so, it was added to the database successfully, and adding the object to the ObservbleCollection is not where the app crashed. It was only when execution jumped back to GoToAsync() that things went sideways.

Again, I am new to .NET MAUI and to be completely honest, I am fairly new to C# (although I have been programming in C/C++ for many years). I was under the (clearly misguided) belief that the application would wait for the GoToAsync() method's execution to complete before jumping to the ApplyQueryAttributes() method in my ViewModel since the ApplyQueryAttributes() method needs the information being passed through GoToAsync() and that the main thread should have to halt for that information to be passed. To me, this seems strange that it would begin executing the GoToAsync() method, jump to the ApplyQueryAttributes() method, and then jump back to the GoToAsync() method. Meanwhile, all of the data being passed through the GoToAsync() method is valid, it is received correctly in my VM and is fully processed, and then the execution of GoToAsync() completes. 🤷

I am only including all of this information for completeness. I don't know how much of this actually applies to the underlying issue with the SwipeView control, of if it matters at all.

Now, on to the solution that worked for me.

The Good Stuff

I am an inherently lazy person, and since I intent to make all the source code to my app open source, I am just going to copy-paste what I have to fix this problem.

TopicCard View XAML

<?xml version="1.0" encoding="utf-8" ?>
<Frame xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       xmlns:local="clr-namespace:CornellPad"
       xmlns:viewmodel="clr-namespace:CornellPad.ViewModels"
       xmlns:entry="clr-namespace:CornellPad.Models"
       x:DataType="entry:TopicModel"      
       x:Class="CornellPad.Views.Cards.TopicCard"
       CornerRadius="20"
       Margin="10,10, 15, 0"
       BorderColor="{AppThemeBinding Light={StaticResource Blue200Accent}, Dark={StaticResource Gray400}}">

    <Frame.GestureRecognizers>
        <TapGestureRecognizer
        Command="{Binding GoToTopicViewCommand, Source={RelativeSource AncestorType={x:Type viewmodel:LibraryViewModel}}}"
        CommandParameter="{Binding .}"/>
    </Frame.GestureRecognizers>

    <Grid ColumnDefinitions="120, Auto"
        RowDefinitions="130"
        Margin="5">

        <Image Grid.Column="0"
            Source="{Binding Icon}"
            HeightRequest="100"
            WidthRequest="100"/>
        <VerticalStackLayout Grid.Column="1"
                            Padding="5">
            <Border
            Padding="10, 6"
            Stroke="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource Gray500}}"
            StrokeThickness="3"
            StrokeShape="RoundRectangle 0,10,10,0"
            VerticalOptions="CenterAndExpand"
            HorizontalOptions="Start"
            BackgroundColor="{AppThemeBinding Light={StaticResource Blue300Accent}, Dark={StaticResource Gray900}}">

                <Label
                Text="{Binding TopicName}"
                Padding="5"
                FontSize="{OnPlatform Default=Subtitle, Android=Small}"/>
            </Border>

            <Label
                Text="{Binding NumberOfNotes, StringFormat='{0} Notes in Topic'}"
                Padding="10"
                VerticalOptions="CenterAndExpand"
                HorizontalOptions="Start"/>
        </VerticalStackLayout>
    </Grid>
</Frame>

There is nothing special about this. Literally the only changed that I had to make in the code-behind was changing the parent class to Frame instead of ContentView. I just copied the XAML from my main view and pasted it in here, with a few alterations to wire everything up, of course.

LibraryView (my main view) XAML

<?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:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
             xmlns:local="clr-namespace:CornellPad"
             xmlns:viewmodel="clr-namespace:CornellPad.ViewModels"
             xmlns:entry="clr-namespace:CornellPad.Models"
             xmlns:cards="clr-namespace:CornellPad.Views.Cards"
             x:DataType="viewmodel:LibraryViewModel"
             x:Class="CornellPad.Views.LibraryView"
             x:Name="LibraryViewPage"
             Title="{Binding Title}">
    <ContentPage.Resources>
        <ResourceDictionary>
            
            <DataTemplate
                x:Key="WithDesktop"
                x:DataType="entry:TopicModel">
                <cards:TopicCard>
                    <FlyoutBase.ContextFlyout>
                        <MenuFlyout>
                            <MenuFlyoutItem
                                Text="Delete"
                                CommandParameter="{Binding .}"
                                Command="{Binding Source={x:Reference LibraryViewPage}, Path=BindingContext.DeleteTopicCommand}"/>
                        </MenuFlyout>
                    </FlyoutBase.ContextFlyout>
                </cards:TopicCard>
            </DataTemplate>
            
            <DataTemplate
                x:Key="WithoutDesktop"
                x:DataType="entry:TopicModel">
                <SwipeView
                    IsVisible="{OnPlatform WinUI=False, MacCatalyst=True, Android=True, iOS=True}">
                    <SwipeView.RightItems>
                        <SwipeItems>
                            <SwipeItemView
                                CommandParameter="{Binding .}"
                                Command="{Binding DeleteTopicCommand, Source={RelativeSource AncestorType={x:Type viewmodel:LibraryViewModel}}}">
                                <Frame
                                    BackgroundColor="IndianRed"
                                    WidthRequest="100"
                                    HeightRequest="100"
                                    VerticalOptions="Center"
                                    CornerRadius="50"
                                    Padding="0">
                                    <Label
                                        Text="Delete"
                                        VerticalOptions="Center"
                                        HorizontalOptions="Center"/>
                                </Frame>
                            </SwipeItemView>
                        </SwipeItems>
                    </SwipeView.RightItems>
                    <cards:TopicCard/>
                </SwipeView>                
            </DataTemplate>
            
        </ResourceDictionary>
    </ContentPage.Resources>
    
    <ContentPage.ToolbarItems>
        <ToolbarItem 
            Text="Add"
            IconImageSource="{AppThemeBinding Light=add_light.png, Dark=add_dark.png}"
            Command="{Binding GoToCreateTopicViewCommand}"/>
    </ContentPage.ToolbarItems>

    <CollectionView
        ItemsSource="{Binding TopicEntries}"
        ItemTemplate="{OnPlatform WinUI={StaticResource WithDesktop}, MacCatalyst={StaticResource WithDesktop}, Default={StaticResource WithoutDesktop}}"
        SelectionMode="None">
    </CollectionView>
</ContentPage>

By defining my DataTemplates as a resource with a key, I can then easily access them according to the platform I am compiling for. I didn't have to change any code-behind anywhere (with the one small exception mentioned above), nor did I have to change any of the code in my ViewModel. By breaking out the XAML markup into it's own separate 'card', I still have one source to define the UI/UX elements for that card. I was very concerned about having duplicate XAML markup, but this seems to circumvent that issue. [Looks around nervously]

As an aside, my xmlns:entry should be named xmns:models, which I plan to change. But as I said, I am inherently lazy and I haven't gotten around to that yet. So, you get the XAML markup with warts and all. 😛

Despite the issues that I have encountered, I have to say that I ❤️ .NET MAUI, even if we have to live with some issues. I hope this helps someone and that you all have a great day.

@indyjason79
Copy link

indyjason79 commented Mar 1, 2024

Thank you @Rabidgoalie for the awesome work-around! I didn't want to turn my template into a view, so I used a ControlTemplate instead and it works great! I was tired of having to maintain 2 templates (1 for swipe and 1 for desktop).

<ControlTemplate x:Key="ItemTemplate">
    <Grid ColumnDefinitions="8,84,*,*"
          RowDefinitions="auto,auto"
          ColumnSpacing="8"
          BackgroundColor="White">
        <Image Grid.Column="1"
               Grid.Row="0"
               Grid.RowSpan="2"
               VerticalOptions="Center"
               HorizontalOptions="Center"
               HeightRequest="36">
            <Image.Source>
                <FontImageSource Glyph="{x:Static icons:Icon.Tag}"
                                 Color="Blue"
                                 Size="36"
                                 FontFamily="{x:Static icons:Font.IconSet}" />
            </Image.Source>
        </Image>

        <VerticalStackLayout Grid.Column="2"
                             Grid.Row="0"
                             Margin="0,8"
                             Grid.RowSpan="2">
            <Label FontSize="14"
                   Text="{Binding Name}"
                   LineBreakMode="TailTruncation"
                   VerticalOptions="Center" />
            <Label FontSize="14"
                   Text="{Binding Info}"
                   LineBreakMode="TailTruncation"
                   Margin="0,5,0,5"
                   TextColor="Gray"
                   VerticalOptions="Center" />
        </VerticalStackLayout>

        <Label Grid.Column="3"
               Grid.Row="0"
               Grid.RowSpan="2"
               Margin="0,0,12,0"
               VerticalOptions="Center"
               HorizontalOptions="End"
               FontSize="16"
               Text="{Binding Price, Converter={StaticResource CurrencyConverter}}"
               TextColor="Purple" />

        <BoxView Grid.Column="0"
                 Grid.ColumnSpan="4"
                 Grid.Row="1"
                 HeightRequest="1"
                 VerticalOptions="End"
                 Color="LightGray" />
    </Grid>
</ControlTemplate>

<DataTemplate x:Key="MobileItemTemplate"
              x:DataType="data:ItemModel">
    <SwipeView>
        <SwipeView.RightItems>
            <SwipeItems>
                <SwipeItem Text="Delete"
                           IsDestructive="True"
                           BackgroundColor="Red"
                           Command="{Binding RemoveCommand}"
                           CommandParameter="{Binding .}"
                           IsVisible="{Binding RemoveCommand, Converter={StaticResource NotNullConverter}}" />
            </SwipeItems>
        </SwipeView.RightItems>

        <ContentView ControlTemplate="{StaticResource ItemTemplate}" />
    </SwipeView>
</DataTemplate>

<DataTemplate x:Key="DesktopItemTemplate"
              x:DataType="data:ItemModel">
    <ContentView ControlTemplate="{StaticResource ItemTemplate}">
        <FlyoutBase.ContextFlyout>
            <MenuFlyout>
                <MenuFlyoutItem Text="Remove"
                                Command="{Binding RemoveCommand}"
                                CommandParameter="{Binding .}"
                                IsEnabled="{Binding RemoveCommand, Converter={StaticResource NotNullConverter}}">
                    <MenuFlyoutItem.IconImageSource>
                        <FontImageSource Glyph="{x:Static icons:Icon.Remove}"
                                         FontFamily="{x:Static icons:Font.IconSet}" />
                    </MenuFlyoutItem.IconImageSource>
                </MenuFlyoutItem>
            </MenuFlyout>
        </FlyoutBase.ContextFlyout>
    </ContentView>
</DataTemplate>

jbe2277 added a commit to jbe2277/waf that referenced this issue Mar 3, 2024
@samhouts samhouts removed the p/1 Work that is important, and has been scheduled for release in this or an upcoming sprint label Apr 23, 2024
@Eilon Eilon removed the legacy-area-controls Label, Button, CheckBox, Slider, Stepper, Switch, Picker, Entry, Editor label May 10, 2024
@bkaankose
Copy link
Contributor

This is a native crash on WinUI3 and has nothing tot much to do with MAUI. I am working on a plain UWP app without MAUI and it's crashing for me as well.

It's reproducible once you have SwipeControl items in a ListView data template and scroll quickly up and down. In UWP it is fired as stowed exception. My investigation with WinDbg showed that this line of code throws it

https://github.com/microsoft/microsoft-ui-xaml/blob/66a7b0ae71c19f89c6a7d86a1986794ad1a1bf09/src/controls/dev/SwipeControl/SwipeControl.cpp#L786

My guess is that once you share LeftItems and RightItems as a resource, interaction tracker code loses child-parent relation with the owner due to UI virtualization.

@PureWeen PureWeen modified the milestones: .NET 8 + Servicing, Backlog Aug 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-controls-swipeview SwipeView external partner/winui WinUI / Project Reunion platform/windows 🪟 t/bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.