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

SwitchPresenter sample in gallery crashes under Windows App SDK #516

Open
1 of 24 tasks
Arlodotexe opened this issue Sep 18, 2024 · 11 comments
Open
1 of 24 tasks

SwitchPresenter sample in gallery crashes under Windows App SDK #516

Arlodotexe opened this issue Sep 18, 2024 · 11 comments
Assignees
Labels
bug Something isn't working regression What was working is now broke sample app 🖼️

Comments

@Arlodotexe
Copy link
Member

Describe the bug

When running the gallery with the Wasdk head on the latest main commit, the 'SwitchPresenter' sample will crash the app:
image

Exception message:

The text associated with this error code could not be found.

Failed to assign to property 'Microsoft.UI.Xaml.Controls.ItemsControl.ItemsSource'. [Line: 21 Position: 19]

Stack trace:

   at WinRT.ExceptionHelpers.<ThrowExceptionForHR>g__Throw|38_0(Int32 hr)
   at ABI.Microsoft.UI.Xaml.IApplicationStaticsMethods.LoadComponent(IObjectReference _obj, Object component, Uri resourceLocator, ComponentResourceLocation componentResourceLocation)
   at Microsoft.UI.Xaml.Application.LoadComponent(Object component, Uri resourceLocator, ComponentResourceLocation componentResourceLocation)
   at PrimitivesExperiment.Samples.SwitchPresenter.SwitchPresenterValueSample.InitializeComponent() in /_/components/Primitives/samples/obj/Debug/net8.0-windows10.0.22621.0/SwitchPresenter/SwitchPresenterValueSample.g.i.cs:line 39

This behavior is not present when running the gallery under UWP.

Steps to reproduce

1. Clone the repo
2. Generate the gallery solution, include the Primitives component and the wasdk multitarget/head.
3. Build and deploy the wasdk gallery 
4. Navigate to the 'SwitchPresenter' sample page and observe crash.

Expected behavior

No crash

Screenshots

No response

Code Platform

  • UWP
  • WinAppSDK / WinUI 3
  • Web Assembly (WASM)
  • Android
  • iOS
  • MacOS
  • Linux / GTK

Windows Build Number

  • Windows 10 1809 (Build 17763)
  • Windows 10 1903 (Build 18362)
  • Windows 10 1909 (Build 18363)
  • Windows 10 2004 (Build 19041)
  • Windows 10 20H2 (Build 19042)
  • Windows 10 21H1 (Build 19043)
  • Windows 10 21H2 (Build 19044)
  • Windows 10 22H2 (Build 19045)
  • Windows 11 21H2 (Build 22000)
  • Other (specify)

Other Windows Build number

No response

App minimum and target SDK version

  • Windows 10, version 1809 (Build 17763)
  • Windows 10, version 1903 (Build 18362)
  • Windows 10, version 1909 (Build 18363)
  • Windows 10, version 2004 (Build 19041)
  • Windows 10, version 2104 (Build 20348)
  • Windows 11, version 22H2 (Build 22000)
  • Other (specify)

Other SDK version

No response

Visual Studio Version

No response

Visual Studio Build Number

No response

Device form factor

No response

Additional context

No response

Help us help you

Yes, I'd like to be assigned to work on this item.

@AndrewKeepCoding
Copy link

AndrewKeepCoding commented Oct 1, 2024

This seems not to be a SwitchPresenter issue. The ComboBox in the sample code is crashing the app. I'm not sure why but the crash can be avoided by not passing an Array of enum to the ComboBox.

These are not fixes:

EnumValuesExtension.cs

protected override object ProvideValue()
{
    // This crashes the app.
    // return Enum.GetValues(Type!);

    // This does not crash the app.
    return Enum.GetNames(Type!);
}

or just:

SwitchPresenterValueSample.xaml.cs

public SwitchPresenterValueSample()
{
    this.InitializeComponent();

    // This crashes the app.
    // this.AnimalPicker.ItemsSource = Enum.GetValues(typeof(Animal));

    // This does not crash the app.
    Animal[] animals = [Animal.Cat, Animal.Dog, Animal.Bunny, Animal.Llama, Animal.Parrot, Animal.Squirrel];
    this.AnimalPicker.ItemsSource = animals;
}

@Arlodotexe Arlodotexe moved this from 🔖 Ready to 🏗 In progress in Toolkit 8.x Oct 8, 2024
@Arlodotexe Arlodotexe self-assigned this Oct 8, 2024
@Arlodotexe
Copy link
Member Author

Arlodotexe commented Oct 8, 2024

Looks like it's an issue with generated code for types passed into EnumValuesExtension.

image

This call to Enum.GetValues(Type) seems to be working as expected. Following the return value in the debugger, the type is passed into a generated LookupVtableEntries method in WinRT.

When it reaches the WinRT.PrimitivesExperiment_SamplesGenericHelpers.GlobalVtableLookup, it isn't finding the PrimitivesExperiment.Samples.SwitchPresenter.Animal[] because it hasn't been generated:

image

This might be related to this other workaround we had to do to get XamlTypeInfo to generate on .NET Native/UWP:

image

Though it seems like this doesn't work for NativeAot/Wasdk.

@Sergio0694 What are your thoughts?

@Sergio0694
Copy link
Member

Interesting, this works fine in my ComputeSharp sample app (UWP, .NET 9).

It seems the CsWinRT generator is missing that Enum.GetValues call. Which I mean, makes sense, since it cannot see the Type argument being passed to it from there. I don't see how that code can work. The extension itself is also marked as not AOT-safe for pretty much the same reason. FYI @manodasanW, do you have any thoughts on this? Seems by design to me.

@michael-hawker
Copy link
Member

michael-hawker commented Nov 1, 2024

For now, I'll update the sample to avoid using the Enum call. @Arlodotexe I'll close this when I open that PR for the SwitchPresenter work I'm looking at. Will use @AndrewKeepCoding's just static array approach, I think.

Mind summarizing the main issues related to the intersection of things in a new issue we can use to track elsewhere? Or should we be opening something on CsWinRT? Since we have the attribute here on the Enum call, shouldn't that get flagged somewhere? Or is that a XAML Compiler thing?

@michael-hawker
Copy link
Member

Huh, actually with the array approach @AndrewKeepCoding shared for the sample I'm still seeing a different error "Value does not fall within the expected range" (though it works with UWP still no problem...)

>	WinRT.Runtime.dll!WinRT.ExceptionHelpers.ThrowExceptionForHR.__Throw|38_0(int hr) Line 134	C#
 	Microsoft.WinUI.dll!ABI.Microsoft.UI.Xaml.Controls.IItemsControlMethods.set_ItemsSource(WinRT.IObjectReference _obj, object value)	Unknown
 	Microsoft.WinUI.dll!Microsoft.UI.Xaml.Controls.ItemsControl.ItemsSource.set(object value)	Unknown

Maybe I won't be fixing this sample then yet... 🤔

michael-hawker added a commit that referenced this issue Nov 1, 2024
Though this sample is still broken with NAOT on WinUI 3... :( Tried a couple of the suggested workarounds, but they did not work on my machine, see #516
@AndrewKeepCoding
Copy link

AndrewKeepCoding commented Nov 1, 2024

@michael-hawker
Might be irrelevant but the workaround above is from a project before the commits after 10/25.
Image

I want to reconfirm it with the latest commits but now I'm facing a bunch of compile errors and it won't even build. 😅

@michael-hawker
Copy link
Member

@AndrewKeepCoding thanks for the info. I based my changes on the latest main, there has been a bump to the WindowsAppSDK version in that time, so I guess there could be a regression here?

@Arlodotexe
Copy link
Member Author

Arlodotexe commented Nov 4, 2024

Yeah this is strange, I'm able to repro the issue @michael-hawker was running into here.

This is no longer an issue with the XAML compiler generating AoT supporting code for WinRT, something else is happening here.

After a few iterations, I landed on a setup that's strongly typed and ensures no null or empty lists are being passed for binding:

Sample .xaml:

<Page x:Class="PrimitivesExperiment.Samples.SwitchPresenter.SwitchPresenterValueSample"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:controls="using:CommunityToolkit.WinUI.Controls"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:local="using:PrimitivesExperiment.Samples.SwitchPresenter"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      xmlns:ui="using:CommunityToolkit.WinUI"
      mc:Ignorable="d">

    <StackPanel>
        <ComboBox x:Name="AnimalPicker"
                  Header="Pick an Animal"
                  ItemsSource="{x:Bind Items, Mode=OneWay}" />
        <controls:SwitchPresenter Padding="16"
                                  TargetType="local:Animal"
                                  Value="{x:Bind AnimalPicker.SelectedItem, Mode=OneWay}">
            <controls:Case Value="Cat">
                <TextBlock FontSize="32"
                           Text="🐈" />
            </controls:Case>
            <controls:Case Value="Dog">
                <TextBlock FontSize="32"
                           Text="🐕" />
            </controls:Case>
            <controls:Case Value="Bunny">
                <TextBlock FontSize="32"
                           Text="🐇" />
            </controls:Case>
            <controls:Case Value="Llama">
                <TextBlock FontSize="32"
                           Text="🦙" />
            </controls:Case>
            <controls:Case Value="Parrot">
                <TextBlock FontSize="32"
                           Text="🦜" />
            </controls:Case>
            <controls:Case Value="Squirrel">
                <TextBlock FontSize="32"
                           Text="🐿" />
            </controls:Case>
        </controls:SwitchPresenter>
    </StackPanel>
</Page>

Sample .xaml.cs

// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

namespace PrimitivesExperiment.Samples.SwitchPresenter;

[ToolkitSample(id: nameof(SwitchPresenterValueSample), "SwitchPresenter Value", description: $"A sample for showing how to use a {nameof(SwitchPresenter)} for state changes from an enum.")]
public sealed partial class SwitchPresenterValueSample : Page
{
    public SwitchPresenterValueSample()
    {
        this.InitializeComponent();
    }

    public ObservableCollection<Animal> Items
    {
        get { return (ObservableCollection<Animal>)GetValue(ItemsProperty); }
        set { SetValue(ItemsProperty, value); }
    }

    public static readonly DependencyProperty ItemsProperty =
        DependencyProperty.Register(nameof(Items), typeof(ObservableCollection<Animal>), typeof(SwitchPresenterValueSample), new PropertyMetadata(new ObservableCollection<Animal>(Enum.GetValues<Animal>())));
}

public enum Animal
{
    Cat,
    Dog,
    Bunny,
    Llama,
    Parrot,
    Squirrel
}

To which we get this error and stack trace:

Value does not fall within the expected range.
   at WinRT.ExceptionHelpers.<ThrowExceptionForHR>g__Throw|38_0(Int32 hr)
   at ABI.Microsoft.UI.Xaml.Controls.IItemsControlMethods.set_ItemsSource(IObjectReference _obj, Object value)
   at Microsoft.UI.Xaml.Controls.ItemsControl.set_ItemsSource(Object value)
   at PrimitivesExperiment.Samples.SwitchPresenter.SwitchPresenterValueSample.XamlBindingSetters.Set_Microsoft_UI_Xaml_Controls_ItemsControl_ItemsSource(ItemsControl obj, Object value, String targetNullValue) in /_/components/Primitives/samples/obj/Debug/net8.0-windows10.0.19041.0/SwitchPresenter/SwitchPresenterValueSample.g.cs:line 27
   at PrimitivesExperiment.Samples.SwitchPresenter.SwitchPresenterValueSample.SwitchPresenterValueSample_obj1_Bindings.Update_Items(ObservableCollection`1 obj, Int32 phase) in /_/components/Primitives/samples/obj/Debug/net8.0-windows10.0.19041.0/SwitchPresenter/SwitchPresenterValueSample.g.cs:line 183
   at PrimitivesExperiment.Samples.SwitchPresenter.SwitchPresenterValueSample.SwitchPresenterValueSample_obj1_Bindings.Update_(SwitchPresenterValueSample obj, Int32 phase) in /_/components/Primitives/samples/obj/Debug/net8.0-windows10.0.19041.0/SwitchPresenter/SwitchPresenterValueSample.g.cs:line 170
   at PrimitivesExperiment.Samples.SwitchPresenter.SwitchPresenterValueSample.SwitchPresenterValueSample_obj1_Bindings.Update() in /_/components/Primitives/samples/obj/Debug/net8.0-windows10.0.19041.0/SwitchPresenter/SwitchPresenterValueSample.g.cs:line 126
   at PrimitivesExperiment.Samples.SwitchPresenter.SwitchPresenterValueSample.SwitchPresenterValueSample_obj1_Bindings.Initialize() in /_/components/Primitives/samples/obj/Debug/net8.0-windows10.0.19041.0/SwitchPresenter/SwitchPresenterValueSample.g.cs:line 120
   at PrimitivesExperiment.Samples.SwitchPresenter.SwitchPresenterValueSample.SwitchPresenterValueSample_obj1_Bindings.Loading(FrameworkElement src, Object data) in /_/components/Primitives/samples/obj/Debug/net8.0-windows10.0.19041.0/SwitchPresenter/SwitchPresenterValueSample.g.cs:line 159
   at WinRT._EventSource_global__Windows_Foundation_TypedEventHandler_global__Microsoft_UI_Xaml_FrameworkElement__object_.EventState.<GetEventInvoke>b__1_0(FrameworkElement sender, Object args)
   at WinRT.GenericTypeInstantiations.Windows_Foundation_TypedEventHandler_2_Microsoft_UI_Xaml_FrameworkElement__object.Do_Abi_Invoke(IntPtr thisPtr, IntPtr sender, IntPtr args)

I'm not sure what to make of this. The problem is in binding the ComboBox, not in the SwitchPresenter or any toolkit helper. @Sergio0694 do you have any ideas? 🤔

@Sergio0694
Copy link
Member

That's weird, ObservableObject<T> should be supported out of the box. Can you reference this CsWinRT build explicitly and try again? We've improved the exception message for invalid casts. I suspect for some reason we're missing the implementation of eg. IIterable<IInspectable*> on that object being used here. That would help confirm it.

cc. @manodasanW

@Arlodotexe
Copy link
Member Author

@Sergio0694 Can confirm, this fixes the issue.

Image

michael-hawker added a commit that referenced this issue Nov 8, 2024
Though this sample is still broken with NAOT on WinUI 3... :( Tried a couple of the suggested workarounds, but they did not work on my machine, see #516
michael-hawker added a commit that referenced this issue Nov 8, 2024
Though this sample is still broken with NAOT on WinUI 3... :( Tried a couple of the suggested workarounds, but they did not work on my machine, see #516
@michael-hawker
Copy link
Member

michael-hawker commented Nov 27, 2024

Updating to CsWinRT 2.2 now provides me with this error, "ICustomProperty support used by XAML Binding for type":

Image

I saw this on the StaggeredPanel too, but talking to Sergio, seems to indicate the use of {Binding} which we are using in a few places still, so that makes sense.

michael-hawker added a commit to CommunityToolkit/Tooling-Windows-Submodule that referenced this issue Nov 27, 2024
…eredLayout in WinUI 3

We were hitting issues with ItemSource setting in WinUI 3, per similar notes in CommunityToolkit/Windows#516
Updating CsWin32 provided better error messages (mostly to do with using {Binding} still in samples), but this appears to resolve the ItemsSource issue I was seeing before
michael-hawker added a commit to CommunityToolkit/Tooling-Windows-Submodule that referenced this issue Dec 2, 2024
…eredLayout in WinUI 3

We were hitting issues with ItemSource setting in WinUI 3, per similar notes in CommunityToolkit/Windows#516
Updating CsWin32 provided better error messages (mostly to do with using {Binding} still in samples), but this appears to resolve the ItemsSource issue I was seeing before
Arlodotexe pushed a commit to CommunityToolkit/Tooling-Windows-Submodule that referenced this issue Dec 3, 2024
…eredLayout in WinUI 3

We were hitting issues with ItemSource setting in WinUI 3, per similar notes in CommunityToolkit/Windows#516
Updating CsWin32 provided better error messages (mostly to do with using {Binding} still in samples), but this appears to resolve the ItemsSource issue I was seeing before
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working regression What was working is now broke sample app 🖼️
Projects
Status: 🏗 In progress
Development

No branches or pull requests

4 participants