C++/CLI DLL and ObservableCollections in a composite class - wpf

I'm implementing a C++/CLI class library that does some low-level device-related stuff and exposes a few managed classes. This library is about to be utilized by a few C# WPF projects.
One of the classes (called CalibrationRecord) consists of a few public properties, and some of them are collections, currently implemented as generic Lists. One of the WPF project has to be able to edit those collections (i.e. implement CRUD operations).
I'm confused whether it would be better to:
A. Implement those collections as ObservableCollections and be able to use them directly from WPF bindings
B. Add another layer in the client app/another DLL and wrap CalibrationRecord in ObservableCalibrationRecord, where collections are ObservableCollections and properties implement INotifyPropertyChanged
I think that B is a "cleaner" solution because this way my class lib has no knowledge of WPF-related interfaces and classes, however, there would be plenty of additional work to implement this layer, and it would be just plain boring boilerplate code, so A seems tempting.
Which solution would you recommend? Or maybe I'm missing some simpler solution?

Personal anecdotes / opinion only here - but I would recommend Option B as well. ObservableCollections in your Model objects can be overkill - the ObservableCollection can raise a lot of notifications that you may not need (as the collection may not be viewed at that time) and seems to blur the business code with your UI code.
One issue I ran into personally while using a similar setup to your Option B, where the data is stored in both a List and in an ObservableCollection, is whether or not you want a copy of the List data in your ObservableCollection or the actual model data object itself. Obviously if you have the actual data in the ObservableCollection, than as the user updates the model object it will be refelected in your List; however, you can run into some design constraints where the Model object needs NotifyPropertyChanged handling, etc. - which can defeat some of the purpose of seperating the two. Otherwise, you have to take the objects in your ObservableCollection and synchronize them back to the List.
I ended up going with the synchronization approach, although that took a bit of extra work when the user was finished with their edits. In the end, the seperation between the two kept the UI editing code delineated from the business operational code / objects, which was worth it.

Related

Using ObservableCollections for Master Detail in Silverlight

Using MVVM in a Silverlight project, I would like to be able to take advantage of the INotifyPropertyChanged interface by using ObservableCollections as the source of the data for a Master/Detail configuration. For the source of the Master list, I would like to use an ObservableCollection that retrieves a minimum number of fields from my database to minimixe loading time, and a different ObservableCollection for my Detail view that includes all fields for editing. Doing this with two different ObservableCollections seems to defeat the INotifyPropertyChanged advantage of using ObservableCollection since the changes are being made to a different ObservableCollection than the one used for the Master List. Is there a way to minimize data loading time for the list and still take advantage of INotifyPropertyChanged?
ObservableCollections notify upon changes in the collection - as in add/remove. They do not handle properties within the objects. The objects themselves have to implement INotifyPropertyChanged.
Objects added to the collections are added by reference. That means that if you update the object...it is updated. It won't make any difference which/how many lists contain the object.

DataGrid and MVVM with Undo/Redo

I'm playing with quite simple interface with buttons and shortcuts for adding, inserting and removing rows of datagrid (underlying bound collection).
There's also a need to implement undo stack.
But...I have no idea how to do with internal logic of this control.
By default DataGrid can remove or add new row automatically and performs many other things on user input (Esc,F2 and so on) thus implicitly changing the bound data.
As commands are to be executed on the VM side undo stack is its (or even M's) business either, yet DataGrid contains internally predefined bindings to DataGrid. commands. And I see no easy mean of 'watching' the changes to the data.
My understanding of the ideal MVVM flow is like that:
User action (View) -> Command (VM) -> Commmand Excution + Undo stack operations. (VM-M)
-> UI changes respectively to VM changes.
I'm confused and need some good advice concerning the implementation.
2 Ways to go about this:
Have your all logic on the ViewModel (POCO Models).
You'll have to have your ViewModel contain an Undo/Redo stack. How you implement it is up to you, but I'd suggest just having the Undo/Redo stacks be of Tuple<String, Object>. Store the property name and the value of the property. It's easier than managing clones. It also gives you the ability for a poor mans "dirtiness" check by seeing if the UndoStack has any items on it.
Give your models some interfaces such as IUndoRedo (Rich Models).
You'll have to have your ViewModels call interface methods to Undo/Redo, but the idea is the same... have an Undo/Redo stack that is composed of Tuple<String, Object>.
If you do decide to want to have a rich model approach, you can look at existing frameworks out there such as CSLA.Net which is made for rich models, though it might be a bit more than what you'll really need. Just throwing it out there in case you want to have really rich models.
A side note: You're ObservableCollection (ItemsSource) should be of ViewModels, not Models. Just throwing that out there in case you were using the Models. That is, don't do ObservableCollection<IEmployee>, but rather ObservableCollection<EmployeeViewModel>. It makes things easier, much easier and more reusable!
Another side note: try to avoid the DataGrid. It makes developers wanna rip their hair out. I'd just roll out your own "Grid" with ListView :)
Normally I build the undo logic into the models themselves. Get them completely working the way you want before you even start thinking about how they are going to be bound to the UI.
I have done an article about undo / redo in MVVM. It is divided in two parts: the first explains undo / redo in general editions and the second explains working with lists:
Part 1: Using the Viewmodel pattern to provide Undo / Redo in WPF
Part 2: Viewmodelling lists
The flow is: User action (View) -> Command (VM) -> Commmand execution modifies the Model -> Model notifies changes to VM -> VM notifies changes to the view.
This way if the model is modified from other source it also refresh the view.
There is also a github project here.
Since your DataGrid is bound to a collection, you can monitor changes to the Collection itself instead of the DataGrid. Use the CollectionChanged event on your collection to watch for added or removed items, and register a PropertyChanged event on all of your collection's items for monitoring edits.
An alternative idea would also be to provide a RevertChanges command instead of UndoChanges. Its much simpler to implement because you only need to store the original collection so you can restore it if needed.

ViewModel tree vs. frequently updating Model tree

In my WPF MVVM application my model is a complex tree of Model objects wich constantly changes at runtime. Model instances come and go at runtime, change their position within the tree and of course change their many properties. My View is almost a one-to-one visual representation of that tree. Every Model instance is in 80% of the cases also a node in the tree.
My question is now how I would design the ViewModel around this? My problem is that there are quite a lot of different Model types with each quite a lot of properties. If I understood MVVM corretcly the view should not communicate with the Model directly so this would mean that I would have to create a ViewModel type for each Model type and have to rewrap each property of the Model type in the ViewModel.
Also the ViewModel would need to "bind" to the propertychanges of the Model to pass it along to the view (using wpf datatbinding). I would need some factory that creates and introduces a ViewModel instance for each Model that appears anew and I would habe to dispose each ViewModel instance when the corresponding Model disappears. I end up keeping track of all instances I created. It is unbelievable how much bloat code is generated dues to this double wrapping.
Is this really a good approach? Each entity and each property more ore less exists twice and I have a lot of extra code keeping Model and View in sync. How do you handle this? Is there a more clever way to solve this?
Does anyone have a reference/sample implementation for this that does it better than I do?
I think you may run into trap of paradigm if you follow this path. MVVM is nothing more than a pattern, which simplifies development in WPF world. If it doesn't - don't use it or revise your approach. I wouldn't spend 80% of my time just to check the "Using MVVM" field.
Now back to your question. Correct me if I'm wrong, but it sounds like you are looking at MVVM from opposite direction: you don't need Model to ViewModel one-to-one correspondence. Usually you create ViewModels based on your View first, and only then on a Model.
Generally you look on a screen mockup from graphic designers, and create corresponding ViewModel, which takes all necessary fields from the Model, wraps/modify/format/combine them to make View development as easy as possible.
You said that your View is almost one-to-one visual representation of the Model. In this case it may have sense to create a very simple ViewModel which exposes root object of your model-tree, and let View consume model directly via that property. Then if you need some View customizations or commands processing you can delegate that to ViewModel.
Sorry for very vague answer. Maybe if you ask more specific question we could dispel the confusion :)...

What are the best characteristics of a datalayer framework for WPF/MVVM applications?

I am creating a WPF/MVVM framework which generates the code for the model classes.
I'm planning to have for each database-table/web-service (e.g. "Customers") two model classes:
a singular model class (e.g. "Customer")
and a plural model class (e.g. "Customers")
The singular model class has all of its properties (FirstName, LastName, etc.) plus all of it methods which make sense for a singular instance, e.g. Save(), Delete(), CalculateSalary(), etc.
The plural model class has a collection of singular model objects, plus the same methods since you would want to also perform on a group of singular objects, e.g. Save(), Delete(), CalculateSalary(), but also particular methods such as Sort(), and methods that made it very easy to certain groups, e.g. LoadAllGoldCustomers(), or even LoadWithSql(string sql), etc.
I've done a framework like this before (PHP) and it made for very easy to write and understand code like this:
Customers customers = new Customers("all");
customers.CalculateSalary();
A couple inherited classes (Item and Items) took most of the code out of the individual singular and plural classes for each database table, which made a very clean environment to program in.
However, I have rarely seen other applications do this singular/plural model class split. Instead, there is almost always just one class for each database table, e.g. Customer and this class has any plural methods necessary, e.g. GetCustomers(string sql), etc.
I just noticed in the WPF Model-View-ViewModel Toolkit 0.1 walkthrough, they have you make two models their "Models" directory two classes:
Customer.cs (fields only)
CustomersDataSource.cs (one List Load() method)
Which seems to be a similar concept, just that the "plural" class is called a DataSource.
So now I am about to make another framework based in WPF/MVVM and can decide how I want to structure the model classes. I want the framework to be:
clear and easy to program against from the ViewModel, hence the clear separation of singular and plural model classes, you should just have to instantiate a singular or plural class and call a method on it and you have your data.
fit in well with the MVVM pattern (which I understand means to keep as simple as possible, just have properties and methods that the ViewModel can call, but implement no WPF-specific features such as INotifyProperityChanged)
want my datalayer to sit above any datasource, so if I use LINQ-to-SQL, I still call my own model classes, and if I want to switch to saving in Oracle, I write a lower data adapter layer for my classes to interact with that.
take advantage of LINQ in the best way possible
I would appreciate feedback from those who have developed datalayers for frameworks especially using WPF/MVVM/Composite Application Library and what characteristics you found worked best, or if you have worked with other frameworks such as CSLA, Subsonic, etc. Also, any experience or ideas on how LINQ changes/simplifies building a datalayer structure. Thanks.
Wow. That's a hard question to answer without having a day to sit down and speak with you. But here goes a shortened version anyway.
First, attempting to port a framework or any characteristics of that framework from one language to another seems like it maybe be trying to shove a square peg in a round hole. While I don't doubt that features (e.g. customer and customers) can be ported, I could certainly argue that they shouldn't be ported. Sticking with the customer.CalculateSalary exmaple, you could use .NET and create an extension method for IEnumerable that did the same thing, eliminating the need for that Customers class. I realize you may have other features as well, but that's just an example. Another example is using LINQ to sort IEnumerable.
Second, I have personally found that having the persistence methods (e.g. Save, Delete, etc.) inside of the object doesn't work well in a large system, particularly when dealing with WCF. It seems to work better in these scenarios to use some type of repository later, which seems like it would also play well with your point of switching to Oracle in the middle of development.
I also want to totally disagree with you on the bullet about fitting well into MVVM. To me, the view model is the glue between the model and the view. It is not only likely that the view model would need to know about the view (hence, WPF specific features), but desired that it know about it. ICommand is a critical interface for the view model to know about, and is one of the WPF-y assemblies (WindowsBase, PresentationCore, PresentationFramework, can't remember which). Also, INotifyPropertyChanged is also critical to data binding and should be implemented in all view models, and has nothing to do with WPF (comes from System.ComponentModel i think?).
That's my two cents. Again, it's really difficult to explain this in a short response to your question. I would recommend using the pattern for a while before making a framework for it. Good luck!

How do I maintain coherency between model and view-model in MVVM pattern?

Problem Statement
I'm writing a very basic WPF application to alter the contents of a configuration file. The data format is an XML file with a schema. I want to use it as a learning project for MVVM, so I have duly divided the code into
Model: C# classes auto-generated from xsd.exe
View-Model: View-friendly representation of the Model.
View: Xaml and empty code behind
I understand how the View-Model can make View-binding a breeze. However, doesn't that leave the View-Model <-> Model semantics very awkward? Xsd.exe generates C# classes with arrays for multiple XML elements. However, at the V-VM level you need Observable Collections.
Questions:
Does this really mean I have to keep two completely different collection types representing the same data in coherence?
What are the best practices for maintaining coherence between the Model and the View-Model?
I'm not a big expert, but I think that is the case yes. The general idea is indeed to propagate change between the view and the viewModel via Binding, and then between the ViewModel and the Model via events (in the Model -> ViewModel direction) or dependency (in the other direction).
I don't know how standard that is, but my understanding of MVVM is that the ViewModel should hold a reference to the model so that when the user modifies the view, the ViewModel should call the appropriate code on the model. The other way round, the Model should raise events when modified, and the ViewModel should update itself accordingly (the ViewModel being an observer to the model).
#Does this really mean I have to keep two completely different collection types representing the same data in coherence?
I think yes. It's pretty boring, but it works quite well. Hopefully, in the future we will have also a code generator to create the ViewModel part.
Karl is working on that: http://karlshifflett.wordpress.com/mvvm/
You need clearly ObservableCollections at the viewmodel so, yes, you will need two
completely different collection types in the model and in the viewmodel.
I have done an article about doing undo / redo in MVVM where you can find a possible solution to this. It uses what I call the MirrorCollection: an ObservableCollection derived class witch automatically obtains his items from a List (the list of the model).
I think it is an interesting solution, you can find the articles here
Part 1: Using the Viewmodel pattern to provide Undo / Redo in WPF
Part 2: Viewmodelling lists (here is the MirrorCollection definition)
Expose Events or delegates in Model and hook to the same in ViewModel, when ever values in the model changes notify to viewmodel via event or delegates and from Viewmodle you can update the UI.
If you want to update it from view model to model as simple as that just call some method pass the new values

Resources