[英]wpf usercontrol positioning not updating instantly while the bound TextBox does
[英]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.