[英]Update property's value on another Window in WPF
我的ViewModel中有一個屬性,其值在BackgroundWorker的DoWork方法中已更改。 當我啟動應用程序並單擊啟動BackgroundWorker的按鈕時,我會看到此屬性的值如何變化。 但是,當我打開新窗口時,即使BackgroundWorker仍在運行,此屬性仍保留其默認值,並且不會更新。
她是我的ViewModel中的代碼:
private string currentData;
...
public ViewModel()
{
...
// Property initialised with a default value
currentData = "BackgroundWorker is not running";
...
}
public string CurrentData
{
get { return this.currentData; }
private set
{
if (this.currentData != value)
{
this.currentData = value;
this.RaisePropertyChanged("CurrentData");
}
}
}
private void DoWork(object sender, DoWorkEventArgs e)
{
isUpdating = true;
...
this.CurrentData = "BackgroundWorker is running...";
for (...)
{
...
if(...)
{
this.CurrentData = "value1";
}
else
{
this.CurrentData = "value2";
...
}
}
}
RaisePropertyChanged方法:
private void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
兩個窗口(MainWindow和newtWindow)的XAML代碼:
<TextBlock Margin="10" MinWidth="250" VerticalAlignment="Center" Text="{Binding CurrentData}" FontSize="12" Foreground="White" HorizontalAlignment="Left" />
BackgroundWorker:
private readonly BackgroundWorker worker;
...
public ImageViewModel()
{
currentData = "BackgroundWorker is not running";
this.worker = new BackgroundWorker();
this.worker.DoWork += this.DoWork;
this.worker.ProgressChanged += this.ProgressChanged;
this.worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_Completeted);
this.worker.WorkerReportsProgress = true;
}
您能告訴我我做錯了什么以及如何解決嗎?
您必須在屬性之外創建一個私有字符串引用,該屬性可以在其中設置值並將其保存在堆棧中,就像這樣(這是wpf如何從text屬性中的文本框中獲取信息)
private string _text; //string that is used as a reference which you can plug your new new window
public string Text
{
get
{
return this._text;
}
set
{
this._text = value;
if (null != PropertyChanged)
{
this.PropertyChanged(this, new PropertyChangedEventArgs ("Text"));
}
}
}
我會避免從后台線程更新綁定到UI的屬性。 我不確定這是否可以解決您的問題,但是我會嘗試使用BackgroundWorker的ReportProgress方法將有關CurrentData的更改通知給ViewModel。 然后,可以在OnProgressChanged事件處理程序中將CurrentData設置為新的String。
public void ReportProgress(int percentProgress, object userState)
您可以將String放入“ userState”對象。
編輯
像這樣的東西:
public ViewModel()
{
...
backgroundWorker.ReportsProgress = true;
backgroundWorker.ProgressChanged += OnProgressChanged;
...
}
private void DoWork(object sender, DoWorkEventArgs e)
{
isUpdating = true;
...
ReportProgress(0,"BackgroundWorker is running...");
for (...)
{
...
if(...)
{
ReportProgress(0,"value1");
}
else
{
ReportProgress(0,"value2");
...
}
}
}
和
private void OnProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.CurrentData = (string)e.UserState;
}
好的,到目前為止,我的理解是:
從您最初的問題:
但是,當我打開新窗口時,即使BackgroundWorker仍在運行,此屬性仍保留其默認值,並且不會更新。
從您的評論到我以前關於設置窗口的DataContext的答案:
<Window.DataContext> <local:ViewModel /> </Window.DataContext>
創建新窗口時,還將創建ViewModel的新實例。 這個新實例也有自己的BackgroundWorker。 當您說“ ...即使BackgroundWorker仍在運行”時,這僅適用於您的第一個窗口,因為必須首先啟動新窗口中的Backgroundworker。
如果兩個窗口都需要相同的DataContext(因此需要相同的BackgroundWorker),則需要將新窗口的DataContext設置為ViewModel的現有實例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.