Я видел другие проблемы, похожие на мои, но я не видел ни одной, которую можно было бы применить, чтобы заставить мой код работать.
Так что я новичок в MVVM, и я пытаюсь получить некоторые вещи, которые выполняются в фоновом потоке, для обновления моего пользовательского интерфейса. Что я замечаю, так это то, что в первый раз запускается пользовательский интерфейс, а фоновый поток выполняется в первый раз, если коллекция IEnumerable <> пользовательский интерфейс не полностью обновлен по отношению к резервным данным. Если коллекция 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 не поддерживает изменения в его SourceCollection из потока, отличного от потока Dispatcher». Я думаю: «Вы шутите?»
Кроме того, я думаю, что изменение объекта в наблюдаемой коллекции автоматически вызовет OnCollectionChanged (), верно?
Заранее всем спасибо.