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

XAML compiler generates invalid C++/WinRT code for bound hstring property #9255

Open
sperrat opened this issue Jan 18, 2024 · 3 comments
Open
Labels
area-XamlCompiler bug Something isn't working team-Markup Issue for the Markup team

Comments

@sperrat
Copy link

sperrat commented Jan 18, 2024

Describe the bug

The code generated to read an hstring property in an x:Bind is missing boxing, and is causing the following error:
error C2679: binary '=': no operator found which takes a right-hand operand of type 'winrt::hstring' (or there is no acceptable conversion)

Steps to reproduce the bug

  1. Create a C++/WinRT UWP project
  2. Define a page and a view model with this IDL:
interface IViewModel
{
    String Name{ get; };
};

[bindable]
[default_interface]
runtimeclass ViewModel : IViewModel
{
    ViewModel();
}

// MainPage.idl
[default_interface]
runtimeclass MainPage : Windows.UI.Xaml.Controls.Page
{
    MainPage();

    static Windows.UI.Xaml.DependencyProperty ViewModelProperty{ get; };
    IViewModel ViewModel;
    Boolean IsReady{ get; };
}
  1. Implement the corresponding C++ code
  2. Add the following xaml; make sure x:Load is present, the error doesn't appear without it:
<!--  MainPage.xaml  -->
<Button
    x:Name="myButton"
    x:Load="{x:Bind IsReady, Mode=OneWay}"
    ToolTipService.ToolTip="{x:Bind ViewModel.Name, Mode=OneWay}">
    Click Me
</Button>
  1. Compile the project; compilation will fail with
    ...\Generated Files\MainPage.xaml.g.hpp(259,21): error C2679: binary '=': no operator found which takes a right-hand operand of type 'winrt::hstring' (or there is no acceptable conversion)
    at
void Update_ViewModel_Name(::winrt::hstring obj, int32_t phase)
{
    if((phase & ((1 << 0) | NOT_PHASED | DATA_CHANGED)) != 0)
    {
        // MainPage.xaml line 14
        if (obj2)
        {
            // obj is properly boxed here
            Set_Windows_UI_Xaml_Controls_ToolTipService_ToolTip(obj2, ::winrt::box_value(obj), std::nullopt);
        }
        else
        {
            // obj is not boxed here
            obj2ToolTipDeferredValue = obj;
        }
    }
}

Expected behavior

This code compiles the string property is properly bound.

Screenshots

No response

NuGet package version

None

Windows version

Windows 11 (22H2): Build 22621, Windows 11 (21H2): Build 22000

Additional context

Workarounds:

  1. The issue doesn't repro without x:Load. If using Visibility instead is acceptable, the code will compile and work.
  2. Manually box the string property:
// BindingHelpers.idl
[default_interface]
static runtimeclass BindingHelpers
{
    static IInspectable ToObject(String value);
}
<!--  MainPage.xaml  -->
<Button
    x:Name="myButton"
    x:Load="{x:Bind IsReady, Mode=OneWay}"
    ToolTipService.ToolTip="{x:Bind local:BindingHelpers.ToObject(ViewModel.Name), Mode=OneWay}">
    Click Me
</Button>
@sperrat sperrat added the bug Something isn't working label Jan 18, 2024
@microsoft-github-policy-service microsoft-github-policy-service bot added the needs-triage Issue needs to be triaged by the area owners label Jan 18, 2024
@bpulliam bpulliam added product-winui2 and removed needs-triage Issue needs to be triaged by the area owners labels Jan 18, 2024
@bpulliam
Copy link
Contributor

Does this also repro in WinUI 3?

@bpulliam bpulliam added needs-author-feedback Asked author to supply more information. area-XamlCompiler team-Markup Issue for the Markup team labels Jan 18, 2024
@sperrat
Copy link
Author

sperrat commented Jan 22, 2024

Indeed; for the repro in WinUI3, take the same view model code as above, and create a custom control to hold the dependency property:

// CustomControl.idl
[default_interface]
runtimeclass CustomControl : Microsoft.UI.Xaml.Controls.Control
{
    CustomControl();

    static Microsoft.UI.Xaml.DependencyProperty ViewModelProperty{ get; };
    IViewModel ViewModel;
}

Then use this control in MainWindow.xaml:

<!-- MainWindow.xaml -->
<local:CustomControl
    x:Name="customControl"
    x:Load="{x:Bind customControl.ViewModel.IsReady, Mode=OneWay}"
    ToolTipService.ToolTip="{x:Bind customControl.ViewModel.Name, Mode=OneWay}" />

The same error will be raised in MainWindow.xaml.g.hpp
MainWindow.xaml.g.hpp(297,21): error C2679: binary '=': no operator found which takes a right-hand operand of type 'winrt::hstring'

@microsoft-github-policy-service microsoft-github-policy-service bot added needs-triage Issue needs to be triaged by the area owners and removed needs-author-feedback Asked author to supply more information. labels Jan 22, 2024
@bpulliam bpulliam removed needs-triage Issue needs to be triaged by the area owners product-winui2 labels Jan 22, 2024
@JaiganeshKumaran
Copy link
Contributor

Duplicate of neglected old issue: #4787.

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

No branches or pull requests

3 participants