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

[BUG] XamlTypeInfo.g.cs generates invalid code for types with required or init properties #8723

Open
mikernet opened this issue Aug 7, 2023 · 5 comments
Labels
bug Something isn't working team-Markup Issue for the Markup team

Comments

@mikernet
Copy link

mikernet commented Aug 7, 2023

Describe the bug

If a type with required properties is used as a public property of a user control / page / dialog / etc (or an internal property that is actually used in XAML), the build fails with an error in XamlTypeInfo.g.cs because the generated code attempts to naively new it up for some reason.

Steps to reproduce the bug

public class User
{
    required public string UserName { get; set; }
}

public class UserInfoControl : UserControl
{
    public User? User { get; set; }
}

This is enough for the build to fail when the property is public, like above. If the property is internal then the control builds, but then compilation fails when the property is actually used from XAML, i.e:

<controls:UserInfoControl User="{x:Bind whatever}" />

In either case, you get:

ERROR: CS9035
Required member 'User.UserName' must be set in the object initializer or attribute constructor.
C:\[project path]\obj\x86\Debug\net7.0-windows10.0.19041.0\win10-x86\XamlTypeInfo.g.cs

Occurs on this line:

        private object Activate_8_User() { return new global::TestWinUIApp.User(); }

I am also having a similar problem with { get; init; } properties where XamlTypeInfo.g.cs sometimes tries to generate a method that sets init props on view models.

Expected behavior

Should just work the same as types that don't have parameterless constructors and not attempt to new it up in XamlTypeInfo.g.cs.

Screenshots

No response

NuGet package version

WinUI 3 - Windows App SDK 1.4 Preview 1: 1.4.230628000-preview1

Windows version

No response

Additional context

No response

@mikernet mikernet added the bug Something isn't working label Aug 7, 2023
@bpulliam bpulliam added the team-Markup Issue for the Markup team label Aug 9, 2023
@codenamelab
Copy link

Same problem. So we can't use types with the required keyword in WinUI?

@mikernet
Copy link
Author

FWIW I haven't found any workarounds that let me use it so I've had to jump some hoops to avoid using both required and init properties anywhere WinUI sees.

@mikernet mikernet changed the title [BUG] XamlTypeInfo.g.cs generates invalid code for types with required properties [BUG] XamlTypeInfo.g.cs generates invalid code for types with required or init-setter properties Feb 9, 2024
@mikernet mikernet changed the title [BUG] XamlTypeInfo.g.cs generates invalid code for types with required or init-setter properties [BUG] XamlTypeInfo.g.cs generates invalid code for types with required or init properties Feb 9, 2024
@karmeye
Copy link

karmeye commented Apr 19, 2024

Is there some attribute one can use on the class or property so that it is not included in XamlTypeInfo.g.cs similar to the WinForms [Browsable (false)], [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]?

Trying to forward the property so it's not used in the XAML didn't solve the problem, i.e.:

private string? MyClassTitle => MyClass.Title;

Ended up declaring all properties that causes the issue like this:

/// <remarks>
/// #415: XamlTypeInfo.g.cs generates invalid code for types with required or init properties.
/// <para>
/// Want this:	
/// <code>
/// public required MyClass ViewModel { get; init; }
/// </code>
/// </para>
/// </remarks>
public MyClass ViewModel { get; set; } = null!;

Because if I let them be nullable then my whole code changes with null checks so it will be cumbersome to go back if issue is ever resolved.

kurema added a commit to kurema/BookViewerApp3 that referenced this issue Apr 25, 2024
Generated XamlTypeInfo.g.cs contained invalid code for @ref. It's not my bug but I can fix it by avoiding @ref.
Related (may be):
microsoft/microsoft-ui-xaml#8723
@mikernet
Copy link
Author

@karmeye What I've done in these situations is usually something like:

private MyClass? _viewModel = null;

public MyClass ViewModel
{
    get => ViewModelHelper.Get(_viewModel);
    set => ViewModelHelper.Set(ref _viewModel, value);
}

internal static class ViewModelHelper
{
    public static T Get<T>(T? field) where T : class
    {
        return field ?? throw new InvalidOperationException("View model was not initialized.");
    }
    
    public static void Set<T>([NotNull] ref T? field, T value) where T : class
    {
        ArgumentNullException.ThrowIfNull(value);
        
        if (field is not null)
            throw new InvalidOperationException("View model has already been set.");

        field = value;
    }
}

@mikernet
Copy link
Author

mikernet commented Jul 13, 2024

Is there any update on this issue? This is becoming a large problem for us. It affects our ability to use modern C# features (if you can even call init a modern feature...it's been around for a very long time) on any shared code that is involved in bindings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working team-Markup Issue for the Markup team
Projects
None yet
Development

No branches or pull requests

4 participants