WinUI3 Desktop XAML数据绑定变更属性时报0x8001010E WinRT错误
你遇到的0x8001010E(RPC_E_WRONG_THREAD)错误是WinUI 3桌面应用和UWP应用的行为差异导致的:UWP的XAML框架会自动将INotifyPropertyChanged的PropertyChanged事件回调封送到UI线程执行,但你使用的0.8.3版本Windows App SDK对应的WinUI 3桌面版没有内置这个自动封送逻辑,触发属性变更通知时必须手动确保运行在UI线程上下文。
解决步骤
1. 给BookSku类添加DispatcherQueue成员
在BookSku构造时获取当前UI线程的调度队列并保存,构造操作需要在UI线程执行:
// BookSku.h 头文件添加成员声明 #include <winrt/Microsoft.UI.Dispatching.h> ... struct BookSku : BookSkuT<BookSku> { private: winrt::Microsoft::UI::Dispatching::DispatcherQueue m_dispatcherQueue{ nullptr }; winrt::hstring m_title; winrt::event<winrt::Windows::UI::Xaml::Data::PropertyChangedEventHandler> m_propertyChanged; ... public: BookSku() { m_dispatcherQueue = winrt::Microsoft::UI::Dispatching::DispatcherQueue::GetForCurrentThread(); } ... }
2. 修改属性变更通知的触发逻辑
触发PropertyChanged前先判断当前线程是否为UI线程,非UI线程就把事件触发逻辑封送到UI线程执行:
void BookSku::Title(winrt::hstring const& value) { if (m_title != value) { m_title = value; if (m_dispatcherQueue.HasThreadAccess()) { m_propertyChanged(*this, winrt::Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L"Title" }); } else { m_dispatcherQueue.TryEnqueue([this]() { m_propertyChanged(*this, winrt::Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L"Title" }); }); } } }
额外逻辑修正
你当前点击处理函数里的写法MainViewModel().BookSku().Title(L"To Kill a Mockingbird");存在错误:这里每次调用都会新建一个临时的MainViewModel实例,修改的不是页面绑定的实例属性,改完界面也不会生效。你需要把页面初始化时创建的MainViewModel实例保存为页面的成员变量,点击时直接修改该成员变量的属性即可。
内容的提问来源于stack exchange,提问作者Eoin
相关产品推荐
相关产品推荐

