嘗試更新ViewModel中的Ui屬性時DispatcherQueue為空 [英] DispatcherQueue null when trying to update Ui property in ViewModel
本文介紹了嘗試更新ViewModel中的Ui屬性時DispatcherQueue為空的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!
問題描述
在桌面應用程序的WinUI 3中,我有一個要更新的屬性,該屬性通過x:Bind
綁定到該UI。
我希望像在WPF中一樣使用Dispatcher
進入UI線程,并避免在更新道具時IM遇到的線程錯誤:
System.Runtime.InteropServices.COMException: 'The application called an interface that was marshalled for a different thread. (0x8001010E (RPC_E_WRONG_THREAD))'
我只是不確定在WinUI3中如何操作,當我嘗試時
DispatcherQueue.GetForCurrentThread().TryEnqueue(() =>
{
AeParty.OnSyncHub = false; // Prop bound in ui using x:Bind
});
我收到此錯誤
DispatcherQueue.GetForCurrentThread()
為空
我也試過了:
this.DispatcherQueue.TryEnqueue(() =>
{
AeParty.OnSyncHub = false;
});
但無法編譯:
然后我發現thisGitHub問題,所以我嘗試:
SynchronizationContext.Current.Post((o) =>
{
AeParty.OnSyncHub = false;
}, null);
這是可行的,但為什么我無法在我的VM中使用調度程序進入UI線程?
推薦答案
DispatcherQueue.GetForCurrentThread()
在實際具有DispatcherQueue
的線程上調用時只返回DispatcherQueue
。如果在后臺線程上調用它,則確實沒有要返回的DispatcherQueue
。
所以訣竅是調用UI線程上的方法,并將返回值存儲在一個變量中,然后從后臺線程使用該變量,例如:
public sealed partial class MainWindow : YourBaseClass
{
public MainWindow()
{
this.InitializeComponent();
}
public ViewModel ViewModel { get; } = new ViewModel();
}
public class ViewModel : INotifyPropertyChanged
{
private readonly DispatcherQueue _dispatcherQueue = DispatcherQueue.GetForCurrentThread();
public ViewModel()
{
Task.Run(() =>
{
for (int i = 0; i < 10; i++)
{
string val = i.ToString();
_dispatcherQueue.TryEnqueue(() =>
{
Text = val;
});
Thread.Sleep(2000);
}
});
}
private string _text;
public string Text
{
get { return _text; }
set { _text = value; NotifyPropertyChanged(nameof(Text)); }
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
這篇關于嘗試更新ViewModel中的Ui屬性時DispatcherQueue為空的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持IT屋!
查看全文