Collection Synchronization and change notification

Topics: Feature requests
Apr 4, 2012 at 10:44 AM

Hi,

Would like to know if Catel supports collection synchronization and change notification from ViewModel to  Model and Vice versa.

Have used MVVM Wrapper for this in our projects.

 

Thanks

Coordinator
Apr 4, 2012 at 10:51 AM

If you map them, you are actually editing exactly the same collection reference. So yes, it keeps it in sync.

Apr 4, 2012 at 11:17 AM

Hi ,

At first thanks for a very quick response.

Lets say if Customer Model class is not derived from DataObjectBase of Catel , it has support for INotifyPropertyChanged only and has below data items

1) List of Shipping addresses(collection)

2) Billing address

3)Orders (collection)

4)FirstName

5) LastName

As per catel we will have  OrderViewModel ,AddressViewModel and then CustomerViewModel will have collection of OrderViewModel and AddressViewModel using Catel attributes (Model and ViewModelToModel).

1) Now in either of the senarios where new address or new order is added to the Model class from any other view , does catel takes care of synchronizing those new additions to  CustomerViewModel ?

2) In a senario where , existing customer address or new Order is added from View (using WPF binding , data will be synchronized to ViewModel) , will the synchronization happens from ViewModel to Model classes.

Thanks.

 

 

 

 

 

Coordinator
Apr 4, 2012 at 11:22 AM

Ok, first of all, I don't think you should create collections of view models on a view model. That;s the whole point of Catel, you only have to instantiate view models when they are absolutely necessary. So, for example, you have a AddressView with AddressViewModel. In your CustomerViewModel, you will have collections of Orders and Addresses. Then the AddressView will automatically instantiate the AddressViewModel when it is needed (so that saves a *lot* of stupid overhead you have to do in other mvvm frameworks).

1) Like I said in the previous paragraph, just maintain the list of models (which is exactly the same as the model). Catel will take care of the view model instantiation when it is needed, so less worries for you about collection synchronization.

2) Yes, because you will add models, not view models. 

Apr 4, 2012 at 11:59 AM

Thanks for the information. Probably if i build a sample it will help me. By the way do we have samples on this front.

Thanks

Coordinator
Apr 4, 2012 at 12:14 PM

Yes, there are a lot of examples. You can find the examples here:

http://catelexamples.codeplex.com/ (you have to download the source under the "source" tab)

The Nested User Controls example does exactly what you want:

Nested User Controls example (is in SL, but works the same)

Dec 15, 2012 at 3:59 AM

I believe in some case I need a viewmodel for each row of DataGrid.

In my application, each row has an boolean column showing if this row is being referred to by some other rows,

and also, each row has a button column that pops up a dialogue box. I do not want to add a "IsReferred" property into the model, neither do I want to add a command to the model object. I need to do this by building a view model for each datagrid row.

The performance problem can be solved by paging. My concern now is how to sync the collection of model to view-models.

Although I somehow managed to solved this sync problem by using the ReactiveCollection, I still expect more features.

1. I want to be able to specify the way of sync, like [ViewModelToMode] attribute does, e.g., explicit, one way, two way. If I use ReactiveCollection, it just reflect immediately, and from model to view-model only, not two-way

2. I want to be able to cancel the edit of collection before the changes are applied to the models, which is already realized in the case of non -collection by using [ViewModelToModel] attribute.

So the ideal way is to solve all these by using the same simple [ViewModelToModel] attribute.

Can we improve this attribute or something?

Coordinator
Dec 30, 2012 at 2:02 PM

I currently see no solution for this. If you have any ideas how we can implement this, please let us know. Even better, you can create a pull request if you have a good idea ;-)

Jan 22, 2013 at 1:59 PM

 

My current solution to collection synchronization problem:

I use Obtics. This is a very interesting framework that automatically finds all the INotifyPropertyChanged and INotifyCollectionChanged interfaces from the lambda and automatically updates the return value of that lambda expression whenever it is out of date.

It does something like this:

result = ExpressionObserver.Execute( () => a +b -c + d) );

suppose "a", "b", "c", and "d" are all notified by INotifyPropertyChanged, the "result" will automatically get update when ever these values change without wiring up in advance.

The most amazing part is that this applies to collection. So I can have viewmodel collection automatically update when model collection changes, Like this:

viewmodelCollection = ExpressionObserver.Execute( modelCollection.Where(...).OrderBy(...).Skip(...).Take(...).Select(model=> new ViewModelItem(model)) );

and that"s all it needs.

But there are some problems in this framework:
1. It only applies to "Expression<>" which means that magic code must be SINGLE LINE only.
2. It only supports one way sync. Which is ok for me as long as I can have direct access to the model collection
3. It only reflect changes immediately. I want to have something like submittable view model collection that I can submit the changes to model collection when I want. But after some research if find it a luxury because collection submission is kind of very complex.

There is also another similar framework called UpdateControls that detects dependency and perform auto-update like Obtics. It does even better in terms of dependency detection, it does not even require your object to implement INotifyPropertyChanged. I believe its design design pattern does not fit many MVVM framework including Catel very well because it requires all your fields to be type Independent<> or Dependent<>.
Collection sync with filter and paging is also supported in this framework.

ReactiveUI which is adopted in Catel, and which I mentioned its ReactionCollection in the above pose, is also a way of doing dependency detection and auto-updating. But in my opinion its only semi-auto because you still need to declare the dependency in advance, and ReactiveCollection does not support paging for the time being. In general, it does not do quite well in handling collection.

I really hope that Catel can have a look at the above frameworks expecially UpdateControls and Obtics and integrate some dependency detection technique into the framework because auto-updating is such a powerful feature that saves you huge work in complex project.

 

Think how clean the code will be if we can do something like this:

int A { get; set; }
int B { get; set; }
int C { get{ return A + B; } }
and C will get updated whenever A or B changes without manually notifying the property change. Think about a ViewModel with 10 properties dependent on other 20 properties whose value further dependent on 5 other properties. Wiring the property change notification alone is a huge and tedious work.

I actually can give more suggestions if you really interested in adding this kind of function.

Please tell us your opinion.

Coordinator
Mar 1, 2013 at 9:22 PM
Can you take a look at the ChangeNotificationWrapper? Does it suite your needs?