嘗試更新ViewModel中的Ui屬性時DispatcherQueue為空 [英] DispatcherQueue null when trying to update Ui property in ViewModel

查看:0
本文介紹了嘗試更新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屋!

查看全文
登錄 關閉
掃碼關注1秒登錄
發送“驗證碼”獲取 | 15天全站免登陸
全免费A级毛片免费看无码播放