I am following the BookStore data binding example, documented at XAML controls; bind to a C++/WinRT property, up to and including the "Bind the button to the Title property" section.
My starting point is a new "Blank App, Packaged (WinUI 3 in Desktop)" project in Visual Studio.
[EDIT] Starting from a "Blank App (C++/WinRT)" project, which is for UWP apps, works perfectly. The problem persists with "WinUI 3 in Desktop" projects.
The initial data binding works and the button content L"Atticus"
is read from the BookSku title property. However calling MainViewModel().BookSku().Title(L"To Kill a Mockingbird");
in the click handler, as directed in article, throws the exception
Exception thrown at 0x00007FFC801B4ED9 (KernelBase.dll) in BookStore.exe: WinRT originate error - 0x8001010E : 'The application called an interface that was marshalled for a different thread.'.
Stepping through the code, the call
m_propertyChanged(*this, Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L"Title" });
in void BookSku::Title(hstring const& value)
is where the exception is thrown from within.
I can change the button content manually, not through the binding property.
The first example in the Data binding in depth article describes a very similar, though slightly less complicated, data binding scenario. It throws the same exception.
I am using latest Microsoft.Windows.CppWinRT version 2.0.210825.3 and Windows App SDK version 0.8.3
This issue #4547 was the key to figuring out the solution. You need to use the Microsoft
namespace, not Windows
. For documentation purposes this is what the BookSku.idl
file should look like:
// BookSku.idl
namespace Bookstore
{
runtimeclass BookSku : Microsoft.UI.Xaml.Data.INotifyPropertyChanged
{
BookSku(String title);
String Title;
}
}