我已经看到了其他类似于我的问题,但我没有看到任何我可以应用到使我的代码工作的问题。
所以我对MVVM很陌生,我正在尝试在后台线程中执行一些东西来更新我的UI。我注意到的是,第一次打开UI,后台线程第一次执行,如果集合是IEnumerable<>,则UI不会根据备份数据完全更新。如果集合为ObservableCollection<>,则会引发错误。
据我所读,对集合的更改需要在dispatcher线程上执行,但是OnPropertyChanged()调用不需要执行。有人,请告诉我这是怎么回事
我正在改变我的_Printers可观察的收藏:
foreach (PrinterViewModel pv in _Printers)
{
DispatcherExec(() =>
{
var abilities = from x in _ServerData.Types
select new PrinterAbility(
new PrintableType() { ID = x.ID, Name = x.Name, NumInProcUnit = x.NumInProcUnit, PrintersMappedTo = x.PrintersMappedTo, SysName = x.SysName },
x.PrintersMappedTo.Contains(pv.Printer.ID)
);
pv.Printer.SetAbilities(abilities);
});
我的DispatcherExec看起来是这样的:
private void DispatcherExec(Action action)
{
//Dispatcher.Invoke((Action)delegate
//{
// action.BeginInvoke(null, null);
//}, null);
Dispatcher.CurrentDispatcher.Invoke((Action)delegate
{
action.Invoke();
}, null);
}
下面是失败的SetAbilities代码:
public void SetAbilities(IEnumerable<PrinterAbility> abilities)
{
if (log.IsInfoEnabled)
log.Info("SetAbilities(IEnumerable<PrinterAbility> abilities): called on printer "+Name);
List<PrinterAbility> l = new List<PrinterAbility>();
abilities.ForEach(i =>
{
i.PrinterAbilityChanged += new PrinterAbilityChangedEventHandler(OnPrinterAbilityChanged);
l.Add(i);
}
);
lock (_Abilities)
{
foreach (PrinterAbility pa in l)
_Abilities.Add(pa);
}
if (log.IsDebugEnabled)
log.Debug("SetAbilities(IEnumerable<PrinterAbility> abilities): leaving");
}
在_Abilities.Add(pa)可观察的集合中,添加它说:“这种类型的CollectionView不支持从不同于Dispatcher线程的线程更改其SourceCollection。”我在想,“你在开玩笑吗?”
此外,我认为对可观察集合中的对象的更改会自动使其调用OnCollectionChanged(),对吗?
提前谢谢各位。
发布于 2010-10-07 21:41:01
对于后台线程,您应该使用与任何WPF控件相关联的Dispatcher,而不是Dispatcher.CurrentDispatcher。
也是
Dispatcher.CurrentDispatcher.Invoke((Action)delegate
{
action.Invoke();
}, null);
是多余的,应该是
wpfDispatcher.Invoke(action, null);
最后,对于第一个块,您通常应该避免将循环变量传递给lambdas,使用临时赋值技巧来绕过这些狡猾的闭包问题。不过,几乎可以肯定的是,这不是问题所在。
https://stackoverflow.com/questions/3885962
复制相似问题