Hi all.
I've seen other issues similar to mine, but i haven't seen any that i can apply to make my code work.
So i'm new to MVVM, and i'm trying to get some stuff that's executing in a background thread to update on my UI. What i'm noticing is that the first time bring up the UI, and the background thread executes the first time, if the collection is IEnumerable<> the UI isn't fully updated against backing data. If the collection is ObservableCollection<>, it throws an error.
From what i've read, changes to collections need to be executed on the dispatcher thread, but OnPropertyChanged() calls do not. So someone, please tell me how this could be happening:
I'm altering my _Printers observable collection:
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);
});
My DispatcherExec looks like so:
private void DispatcherExec(Action action)
{
//Dispatcher.Invoke((Action)delegate
//{
// action.BeginInvoke(null, null);
//}, null);
Dispatcher.CurrentDispatcher.Invoke((Action)delegate
{
action.Invoke();
}, null);
}
And here's the SetAbilities code that fails:
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");
}
On the _Abilities.Add(pa) observable collection add it says "This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread." I'm thinking, "are you joking?"
Further, I would think that a change to an object in the observable collection would automatically make it call OnCollectionChanged(), is that right?
Thanks in advance everyone.