我知道这是一个经常被问到的问题,但我现在试图解决它至少一周...阅读这么多线程,下载数百万个不同的MVVM模式示例等等......
我只是想在我的MVVM模型视图第一种方法中更新一个愚蠢的标签:
void StartUpProcess_DoWork(object sender, DoWorkEventArgs e)
{
SplashWindow splash = new SplashWindow();
var ViewModel_Splash = new VM_SplashWindow();
splash.DataContext = ViewModel_Splash;
splash.Topmost = true;
splash.Show();
ViewModel_Splash.DoWork();
}
完整的ViewModel:
public class VM_SplashWindow:VM_Base
{
#region Properties
private string _TextMessage;
public string TextMessage
{
get
{
return _TextMessage;
}
set
{
if(_TextMessage != value)
{
_TextMessage = value;
base.OnPropertyChanged("TextMessage");
}
}
}
#endregion
#region Methods
public void DoWork()
{
this.TextMessage = "Initialize";
for(int aa = 0; aa < 1000; aa++)
{
this.TextMessage = "Load Modul: " + aa.ToString();
Thread.Sleep(5);
}
this.TextMessage = "Done";
Thread.Sleep(1000);
}
#endregion
}
基地的一小块:
public abstract class VM_Base:INotifyPropertyChanged, IDisposable
{
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(propertyName);
handler(this, e);
}
}
#endregion
}
最后是观点:
<Label Height="28" Margin="19,0,17,15" Name="label2" VerticalAlignment="Bottom"
Content="{Binding Path=TextMessage}" Foreground="White" />
如果我在viewmodel的构造函数中为TextMessage属性设置初始值,则此初始值将显示在splash.Show()命令之后。
在DoWork-Method中设置TextMessage属性会引发onPropertyChangedEvent,但不幸的是它不会更新窗口中的标签。我不知道该怎么做......我真的很期待寻求帮助。提前谢谢了!
也许我应该提一下,StartUpProcess_DoWork正在一个自己的STAThread
中运行亲切的问候,flo
答案 0 :(得分:0)
显然,您在GUI线程中执行了大量工作。使用Thread.Sleep
,您甚至可以暂停GUI线程。因此,它将无法更新控件。
解决方案是为DoWork
方法使用不同的线程。这可以通过BackgroundWorker
轻松实现。如果向工作程序提供GUI调度程序对象,则可以从该处发出GUI更改。虽然最好使用ProgressChanged
- 事件,但如果可能的话。