【发布时间】:2010-10-07 21:19:40
【问题描述】:
我看到了与我类似的其他问题,但我还没有看到任何我可以应用以使我的代码工作的问题。
所以我是 MVVM 的新手,我正在尝试获取一些在后台线程中执行的东西来更新我的 UI。我注意到的是,第一次调出 UI,并且后台线程第一次执行,如果集合是 IEnumerable,则 UI 没有完全针对支持数据进行更新。如果集合是 ObservableCollection,则会抛出错误。
根据我的阅读,对集合的更改需要在调度程序线程上执行,但 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(),对吗?
提前谢谢大家。
【问题讨论】:
标签: c# wpf multithreading mvvm