DynamicListBase<T> Model.SaveItem possible bug?

DynamicListBase<T> Model.SaveItem possible bug?

Old forum URL: forums.lhotka.net/forums/t/10021.aspx


Devman posted on Thursday, February 03, 2011

Hi,

Im using a View Model that has a DynamicListBase as the Model type. I have a ListBox who's ItemSource is bound to the model property, SelectedIndex  is also bound to a SelectedIndex property on the VM.

I navigate the ListBox items using the SelectedIndex property on the VM, the bindings work as expected...So far so good.

I call Model.AddNew() to add the the collection,select it, and the selected index property on the vm is correctly set.

The problem arrises however when I call Model.SaveItem(). After calling this,When I try to select this item in the listbox, the bound selected index property on the vm is set to -1..Its as if there has not been a propertychanged notification fired or something similar.

To confirm, this issue only arrises after calling Model.SaveItem(..) .

The only way i can correct this is if i reset the ItemSource to null and then back to the model.

Any thoughts?

 

Regards

David

 

JonnyBee replied on Thursday, February 03, 2011

Hi,

DynamicListBase will save changes immediately to each row when another object is selected.
So the ViewModel is created for BusinessListBase lists - not DynamicListBase lists and will not work well with DynamicListBase .

Se also this thread: http://forums.lhotka.net/forums/p/9978/46789.aspx#46789

Devman replied on Thursday, February 03, 2011

Many thanks for the quick reply,

I've looked at the other thread and tried this senario with a ListBox and DataGrid with the same results.  Im confused, what is the DynamicListBase used for then if you suggest using BusinessListBase instead??   I thought for our scenario DynamicListBase would be a good fit as each BB within the list needs to be saved individually, due to them containing large binary data. Therefore using BLB could result in saving many objects with large binary data at once

If DLB is not going to work for us and BLB give this undesired potential mass saving of data, what would you suggest be the best way forward?

Best Regards

David

ajj3085 replied on Thursday, February 03, 2011

The DynamicList is what you want in your case, so my guess would be that you don't need a ViewModel in the mix at all since saving / canceling is done automatically via databinding, so the ViewModel isn't buying you anything (or very much).  Maybe a simpler ViewModel based on DependencyObject is all you really need.

Devman replied on Friday, February 04, 2011

Andy/Jonny

Ive removed the csla ViewModel classes from the equation and now have the following VM

MyViewModel :INotifyPropertyChanged...

However I still have the same Issue and thats with the DLB.SaveItem(). When a DLB is bound to a ListBox/DataGrid and a new entry is saved via SaveItem,(be that automatically in the DataGrid instance), when selecting the item in the list/datagrid the SelectedIndex property is set to -1 as i said in my initial post. Maybe im missing something but VM, or no VM, this seems like a problem with the DLB and change notifications not being sent correctly.

I need DLB for my senario but cant use/bind to it without  refreshing the bound control's itemssource on the saved event of DLB. Im using this work around but surely this cant be right??

RockfordLhotka replied on Friday, February 04, 2011

Is this WPF or Silverlight?

The WPF datagrid is notoriously poor in terms of handling data changed events, and there are a couple issues that I've been unable to solve.

If this is failing in SL I'm more concerned, because that datagrid is much more reliable.

Devman replied on Monday, February 07, 2011

Hi Rocky,

This is WPF.....and having looked at the source i can see a problem.  In DLB.SaveItem() I see there has been a change regarding Silverlight DataGrid not supporting the replace action, which calls OnCollectionChanged twice with Remove and then Add as params.

However, with WPF,replacing an item in the list OnCollectionChanged is called once with Replace as the param. The base.OnCollectionChanged() is not being fired in this instance. 

 

 protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
      // SL Data Grid's DataGridDataConnection object does not support replace action.  
      // It throws an excpetioon when this occurs.
      if (this.RaiseListChangedEvents && (e.Action != NotifyCollectionChangedAction.Replace || RaiseReplaceEvents))
        base.OnCollectionChanged(e);
    }

Regards

David


Devman replied on Monday, February 07, 2011

After looking at this further, If i set RaiseReplaceEvents to True, the base.OnCollectionChanged() is called twice but an InvalidOperationException is thrown on the second call.

"Cannot find removed item."

So it seems the only way for me to get this working in WPF is to replace the following code within DLB.SaveItem();

Replace;

 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, result, item));

 

With;

 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, index));
 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, this[index], index));

 

RockfordLhotka replied on Monday, February 07, 2011

Thank you for continuing to dig into this issue, I appreciate it.

What I find interesting about this solution, is that I had to do a similar thing for the SL datagrid because it didn't honor the Replace action correctly either...

RockfordLhotka replied on Monday, February 07, 2011

http://www.lhotka.net/cslabugs/edit_bug.aspx?id=900

Copyright (c) Marimer LLC