我对MVVM相对来说比较新,我想为MVVM WPF应用程序编写一个基本状态栏。我认为我有一些东西的要点,但出于某种原因,状态栏并不总是更新,我不知道为什么。StatusBar并不总是更新
在我的ViewModel,我有更新的基本属性,当我改变的状态消息:
public string StatusMessage
{
get { return _statusMessage; }
set
{
if (value == _statusMessage) return;
_statusMessage = value;
base.OnPropertyChanged(() => this.StatusMessage);
}
}
我OnPropertyChanged方法(我在实现INotifyPropertyChanged基ViewModel类)看起来像这样(得到了冈瑟Foidl这个想法,希望我能居功,因为我认为这是华而不实的,但我不是很聪明):
protected virtual void OnPropertyChanged<T>(Expression<Func<T>> exp)
{
MemberExpression me = exp.Body as MemberExpression;
string propName = me.Member.Name;
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propName));
}
}
无论如何,这一切都为我所有的控件的伟大工程,除了一。在我MainWindow.xaml文件,我有一个绑定到上述财产,像这样一个StatusBarItem控制(XAML的其余部分被剪短空间原因):
<StatusBarItem Grid.Column="0">
<TextBlock TextTrimming="CharacterEllipsis" Text="{Binding Path=StatusMessage}" />
</StatusBarItem>
当我运行我的应用程序(它击中几个数据库除了从模板和其他相当资源密集的东西中生成一个文档之外),一些但不是全部的消息显示在状态栏上。我已经调试并验证了这些消息全部进入了上面的StatusMessage属性(和随后的私有变量),但它们似乎并没有在UI中刷新。
我看了几个使用ProgressBar控件的BackgroundWorker实例的例子,但没有看到任何StatusBarItem控件,并且我不确定如何将一个转换为另一个。我已经在之前的C#4.0和WPF应用程序中使用了任务,并且认为它可能是一个很好的方法,但我还没有真正弄清楚如何/在哪里指定UI任务(我称之为“我以前总是在MainWindow的代码隐藏中做到这一点,但我正在努力争取一个零代码保持与MVVM保持一致)。
我非常肯定,多线程方法是要走的路;我只是不太了解一种方法(我知道一点这个和一点点)以使其工作。我确实看到一些直接使用旧的线程方法的帖子,但是我几乎不用多线程编程,直到我开始使用.NET 4.0的任务(发现它们更易于理解和跟踪),所以我有有点麻烦使他们感觉。
任何人都可以怜悯我,并指出我在正确的方向,或建议进一步的调试,我可以做什么?谢谢!
我有类似的更新TextBlock问题,你到底找到了解决方案吗? – 2011-06-14 08:01:57
我**能够通过将我的UI TaskScheduler传递到ViewModel并对从所述调度程序生成的任务执行更新来获得任务代码的工作。如果时间允许,我会在单独的答案中发布代码示例。 – 2011-06-17 12:10:41
@Julien,这就是我所做的。当我在我的App.xaml.cs文件中初始化我的ViewModel时,我传入了两个TaskFactory实例:一个用于UI:新的TaskFactory(TaskScheduler.FromCurrentSynchronizationContext())'我调用了'UiTasks',一个用于其他任务'任务.Factory'我称之为'DefaultTasks'。然后,我确定我的繁重工作在默认任务工厂下运行,并使用UI工厂更新了我的属性:'this.UiTasks.StartNew((=)this.StatusMessage = myMessage;});'这似乎是个诀窍。如果你愿意,我会很乐意给你一个更详细的例子。祝你好运! – 2011-06-19 14:04:04