WinUI 3 Desktop XAML 数据绑定 - WinRT 发生错误 - 当 属性 更改时出现 0x8001010E

WinUI 3 Desktop XAML Databinding - WinRT originate error - 0x8001010E when the Property is changed

我正在关注 XAML controls; bind to a C++/WinRT property 中记录的 BookStore 数据绑定示例,直到并包括“将按钮绑定到标题 属性”部分。

我的起点是 Visual Studio 中的新“空白应用程序,打包(桌面中的 WinUI 3)”项目。

[编辑] 从适用于 UWP 应用程序的“空白应用程序 (C++/WinRT)”项目开始,运行完美。 “桌面中的 WinUI 3”项目仍然存在此问题。

初始数据绑定有效,按钮内容 L"Atticus" 从 BookSku 标题 属性 中读取。但是,按照文章中的指示,在点击处理程序中调用 MainViewModel().BookSku().Title(L"To Kill a Mockingbird"); 会引发异常

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.'.

单步执行代码,调用

m_propertyChanged(*this, Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L"Title" });

in void BookSku::Title(hstring const& value) 是从内部抛出异常的地方。

我可以手动更改按钮内容,而不是通过绑定 属性。

Data binding in depth 文章中的第一个示例描述了一个非常相似但稍微不那么复杂的数据绑定场景。它抛出相同的异常。

我正在使用最新的 Microsoft.Windows.CppWinRT 版本 2.0.210825.3 和 Windows App SDK 版本 0.8.3

The application called an interface that was marshalled for a different thread

问题是你在no-ui线程中更新了属性,所以会抛出上面的异常,你可以使用下面的方法回到ui-更新 属性.

之前的线程
co_await winrt::resume_foreground(Dispatcher(), CoreDispatcherPriority::Normal);

详情请参考document here

这个问题 #4547 是找出解决方案的关键。您需要使用 Microsoft 命名空间,而不是 Windows。出于文档目的,BookSku.idl 文件应如下所示:

// BookSku.idl
namespace Bookstore
{
    runtimeclass BookSku : Microsoft.UI.Xaml.Data.INotifyPropertyChanged
    {
        BookSku(String title);
        String Title;
    }
}