microsoft / microsoft/microsoft-ui-xaml

Different custom enum boxing behavior in C++ and C#

Open
#11,885 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug needs-triage
Dominant language
C++
Stars
8.4k
Forks
942
Avg merge
2d 7h
Merged PRs (30d)
105

Description

Describe the bug

Assigning a custom enum type in xaml has different boxing behavior. When you assign a custom enum (not a winui's built-in enum) to a Object type, using the following code in a C++winrt component

        void EnumProperty(winrt::Windows::Foundation::IInspectable const& value)
        {
            auto propertyValue = value.as<winrt::Windows::Foundation::IPropertyValue>();
            auto type = propertyValue.Type();
        }

You get OtherType in a C++ consuming project, and Int32 in a C# consuming project.

Why is this important?

This bug is extremely hard to find when making a runtime component that's targeting for both C++ and C#.

Steps to reproduce the bug
  1. Create both a C++ and C# winui3 project from the templates
  2. Create a C++ runtime component project, with this class and a custom enum type
    enum ContentAlignment
    {
        Right,
        Left,
        Vertical
    };

    [bindable]
    [default_interface]
    runtimeclass ViewModel
    {
        ViewModel();
        Object EnumProperty;
    }

In the code behind:

    struct ViewModel : ViewModelT<ViewModel>
    {
        winrt::Windows::Foundation::IInspectable EnumProperty()
        {
            return nullptr;
        }

        void EnumProperty(winrt::Windows::Foundation::IInspectable const& value)
        {
            auto className = winrt::get_class_name(value);
            auto propertyValue = value.as<winrt::Windows::Foundation::IPropertyValue>();
            auto type = propertyValue.Type();
        }
    };
  1. Now in both consuming winui3 project, use this xaml
<Window
   ...
    xmlns:component="using:RuntimeComponent">

    <Grid x:Name="RootGrid" HorizontalAlignment="Stretch">
        <Grid.Resources>
            <component:ViewModel x:Name="MyViewModel">
                <component:ViewModel.EnumProperty>
                    <component:ContentAlignment>Right</component:ContentAlignment>
                </component:ViewModel.EnumProperty>
            </component:ViewModel>
        </Grid.Resources>
    </Grid>
</Window>
  1. For the C++ winui project, simply add a project reference to the runtime component project
  2. For the C# winui project, add a <CsWinRTIncludes> tag in the csproj (See my repro project link below)
  3. Put a breakpoint on the line auto type = propertyValue.Type();
  4. Enable native debugging in the C# project so breakpoint will hit.
Actual behavior
C++ C#
Image Image

Also notice C# project seems to lost the enum type info completely.

Expected behavior

No response

Screenshots

No response

NuGet package version

2.4

Windows version

Windows 11 (24H2): Build 26120

Additional context

Repro project. Open the solution, build and run 36-DifferentXamlBoxingBehaviorCpp for C++ project and DifferentXamlBoxingBehaviorCSharp for C# project.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Open the linked repro project and run both 36-DifferentXamlBoxingBehaviorCSharp and 36-DifferentXamlBoxingBehaviorCSharp as described, then inspect the ViewModel.EnumProperty setter and the breakpoint at propertyValue.Type(). Compare the custom enum boxing results in the C++ and C# consuming projects; done means the behavior and enum type information are consistent across both paths.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, csharp
Domain
desktop
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.