Microsoft-ui-xaml: 'XamlBindings': undeclared identifier in C++/WinRT

Created on 11 May 2020  路  11Comments  路  Source: microsoft/microsoft-ui-xaml

Describe the bug
I get the compiler error 'XamlBindings': undeclared identifier when using x:Bind in a ControlTemplate as part of a XAML document that isn't in the root namespace with C++/WinRT.

Steps to reproduce the bug

  1. Create a new C++/WinRT UWP app (with minimum version 17763)
  2. Create a page that isn't in the project's root namespace (ex BlankApp1.Foo.MyPage)
  3. Within that page, retemplate a control and use x:Bind in the template, for example
    xaml <Button x:Name="myButton" Click="ClickHandler"> <Button.Template> <ControlTemplate TargetType="Button"> <ContentPresenter Width="{x:Bind Width}" ></ContentPresenter> </ControlTemplate> </Button.Template> Click Me </Button>
  4. Try building the project.
  5. Observe a compiler error in Foo.MyPage.xaml.g.hpp

Expected behavior
It builds.

Version Info
Visual Studio 16.6.0 Preview 6.

NuGet package version:
C++/WinRT 2.0.200508.4


| Windows 10 version | Saw the problem? |
| :--------------------------------- | :-------------------- |
| Insider Build (19041) | Yes |
| November 2019 Update (18363) | |
| May 2019 Update (18362) | |
| October 2018 Update (17763) | |
| April 2018 Update (17134) | |
| Fall Creators Update (16299) | |
| Creators Update (15063) | |


| Device form factor | Saw the problem? |
| :-------------------- | :------------------- |
| Desktop | Yes |
| Mobile | |
| Xbox | |
| Surface Hub | |
| IoT | |

Additional context
Full output:

1>------ Build started: Project: BlankApp2, Configuration: Debug Win32 ------
1>App.cpp
1>Foo.MainPage.cpp
1>XamlTypeInfo.g.cpp
1>T:\Projects\BlankApp2\Generated Files\Foo.MainPage.xaml.g.hpp(81,55): error C2065: 'XamlBindings': undeclared identifier
1>T:\Projects\BlankApp2\Generated Files\Foo.MainPage.xaml.g.hpp(71): message : while compiling class template member function 'winrt::Windows::UI::Xaml::Markup::IComponentConnector winrt::BlankApp2::Foo::implementation::MainPageT<winrt::BlankApp2::Foo::implementation::MainPage>::GetBindingConnector(int32_t,const winrt::implements<D,winrt::BlankApp2::Foo::MainPage,winrt::composing,winrt::Windows::UI::Xaml::Controls::IPageOverrides,winrt::Windows::UI::Xaml::Controls::IControlOverrides,winrt::Windows::UI::Xaml::Controls::IControlOverrides6,winrt::Windows::UI::Xaml::IFrameworkElementOverrides,winrt::Windows::UI::Xaml::IFrameworkElementOverrides2,winrt::Windows::UI::Xaml::IUIElementOverrides,winrt::Windows::UI::Xaml::IUIElementOverrides7,winrt::Windows::UI::Xaml::IUIElementOverrides8,winrt::Windows::UI::Xaml::IUIElementOverrides9,winrt::Windows::UI::Xaml::Markup::IComponentConnector,winrt::Windows::UI::Xaml::Markup::IComponentConnector2>::IInspectable &)'
1>        with
1>        [
1>            D=winrt::BlankApp2::Foo::implementation::MainPage
1>        ]
1>T:\Projects\BlankApp2\Generated Files\winrt\Windows.UI.Xaml.Markup.h(361): message : see reference to function template instantiation 'winrt::Windows::UI::Xaml::Markup::IComponentConnector winrt::BlankApp2::Foo::implementation::MainPageT<winrt::BlankApp2::Foo::implementation::MainPage>::GetBindingConnector(int32_t,const winrt::implements<D,winrt::BlankApp2::Foo::MainPage,winrt::composing,winrt::Windows::UI::Xaml::Controls::IPageOverrides,winrt::Windows::UI::Xaml::Controls::IControlOverrides,winrt::Windows::UI::Xaml::Controls::IControlOverrides6,winrt::Windows::UI::Xaml::IFrameworkElementOverrides,winrt::Windows::UI::Xaml::IFrameworkElementOverrides2,winrt::Windows::UI::Xaml::IUIElementOverrides,winrt::Windows::UI::Xaml::IUIElementOverrides7,winrt::Windows::UI::Xaml::IUIElementOverrides8,winrt::Windows::UI::Xaml::IUIElementOverrides9,winrt::Windows::UI::Xaml::Markup::IComponentConnector,winrt::Windows::UI::Xaml::Markup::IComponentConnector2>::IInspectable &)' being compiled
1>        with
1>        [
1>            D=winrt::BlankApp2::Foo::implementation::MainPage
1>        ]
1>T:\Projects\BlankApp2\Foo.MainPage.h(8): message : see reference to class template instantiation 'winrt::BlankApp2::Foo::implementation::MainPageT<winrt::BlankApp2::Foo::implementation::MainPage>' being compiled
1>T:\Projects\BlankApp2\Generated Files\Foo.MainPage.xaml.g.hpp(81,45): error C2672: 'winrt::make_self': no matching overloaded function found
1>T:\Projects\BlankApp2\Generated Files\Foo.MainPage.xaml.g.hpp(88,1): error C2974: 'winrt::make_self': invalid template argument for 'D', type expected
1>T:\Projects\BlankApp2\Generated Files\winrt\base.h(7458): message : see declaration of 'winrt::make_self'
1>Done building project "BlankApp2.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

This also affects other use cases, like a control inheriting from another and retemplating the parent, binding some values to its own properties. (that was how I found it, because my controls are under the MyRootNamespace.Controls namespace)

I cannot use TemplateBinding because I would like to provide a TargetNullValue fallback, which is not possible with TemplateBinding.

You can find my use case here https://github.com/TranslucentTB/TranslucentTB/tree/develop. The issue can be reproduced simply by building the Xaml project which has no other dependencies than the community toolkit's XamlApplication, C++/WinRT and the VCTRForwarders.

Moved from https://github.com/microsoft/cppwinrt/issues/614

needs-winui-3 team-Markup

Most helpful comment

We'll also backport both fixes for Windows.UI.Xaml, but to set expectations for a timeline, it won't be available until the Windows SDK release in mid-2021 due to the Windows shipping schedule.

All 11 comments

According to documentation linked below, x:Bind in control templates is supported since 17763: https://docs.microsoft.com/en-us/windows/uwp/xaml-platform/templatebinding-markup-extension#xbind-in-controltemplate

It indeed works fine when using C#, and the C++/WinRT code for it is generated as well, it's just a omission of a namespace qualifier for a make_self<> call in a part of the codegen that is causing trouble.

According to documentation linked below, x:Bind in control templates is supported since 17763:

@sylveon yes it has! Glad that you were able to discover that :)

I'm currently having to debug a runtime binding issue and the lack of x:Bind is being severely felt :(

Having a compile time error would be much easier to correct.

repro.zip
Here's a minimum repro project

Could reproduce similar issue in WinUI3 as well. I have a PostsPage in root-namespace.Presentation.UI.Posts and when building the project the compiler complains it cannot find XamlBindingTrackBase.

Screenshot
Notice how XamlingBindingTrackBase lack namespace prefix, while ReferenceTypeXamlBindings below have it.
image

@sylveon, gotcha, so this is just a simple bug in the C++/WinRT codegen, then?

@RealTommyKlein can you take a look at this? This sounds like a simple fix we could make in the 3.0 timeframe?

Yes, it's simply missing a namespace qualifier

Yeah we can fix this for WinUI 3. I've fixed the XamlBindingTrackingBase issue locally, will also convert the original repro app to WinUI 3 and verify the XamlBindings issue is fixed too.

Would love to see this backported to the system XAML compiler, since I use XAML Islands so I would have to wait for WinUI 3.1 to get the fix

We'll also backport both fixes for Windows.UI.Xaml, but to set expectations for a timeline, it won't be available until the Windows SDK release in mid-2021 due to the Windows shipping schedule.

Was this page helpful?
0 / 5 - 0 ratings