簡體   English   中英

立即更新綁定的WPF屬性

[英]Updating bound WPF property instantly

我在窗口上有一個文本框,用於報告操作的狀態和/或成功。 它綁定到ViewModel的屬性。

因此,當用戶激活可能要花一些時間的操作時,我不想讓他知道該操作已在textBox中開始。 問題在於,直到操作完成后,他才寫到文本框中。

我想這是因為線程沒有給UI提供執行工作的機會,但不確定。

public class ViewModel : INotifyPropertyChanged
{
        private string _report;
        public string Report
        {
            get { return _report; }
            set
            {
                _report = value;
                RaisePropertyChanged("Report");
            }
        }

        public void DoHeavyAction()
        {
            Report += "Heavy action readying";

            ReadyHeavyAction();

            Report += "Heavy action starting";

            var result = DoTheHeavyAction();

            if(!result.success)
            {
                report += "Heavy action failed";
                return;
            }

            Report += result.value;
        }
}

在這種情況下,程序滯后2秒,然后整個過程出現:

Heavy action readying
Heavy action starting
Heavy action failed

而不是一一出現。

我可以以某種方式使用調度程序來更新視圖(請注意我正在使用MVVM)。

是的,這很容易。 您的繁重操作在單獨的線程中運行,並且您將進度報告為

Dispatcher.Invoke((Action)(() => {
    Report.value = "Started";
}));

編輯:
在實際情況下,該操作由ICommand激活。 所述ICommand是從UI調度的,因此它位於UI線程中。 因此,問題在於用戶界面(及其更新)被繁重的操作阻塞了。

解決方案是在命令到達時啟動一個新線程,並在那里進行工作。 可以使用上面的示例代碼來更新UI。

此解決方案有一些替代方法,但是無論如何,所有這些方法都是隱式啟動后台線程中的任務。 一種流行的好方法是使用BackgroundWorker並在其ProgressChanged事件中更新狀態(請注意,此事件出現在UI線程中,因此在這種情況下您無需使用Dispatcher)。

您可以將“繁重的工作”移至后台任務以使其脫離UI線程。

var task = Task.Factory.StartNew(() => DoHeavyAction());
Report += "Heavy Action Starting";
task.Wait();

您為什么不使用BackgroundWorker並設置ProgressChanged事件?

例:

var worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.ProgressChanged += WorkerReportProgress;
...

private static void WorkerReportProgress(object sender, ProgressChangedEventArgs e) {
    report += e.UserState.ToString();
}

在DoWork中做類似

private static void DoHeavyAction(object sender, DoWorkEventArgs e) {
    var worker = (BackgroundWorker)sender;
    worker.ReportProgress(0, "Heavy action readying");
    ReadyHeavyAction();
    ...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM