Showing posts with label DM-V-VM. Show all posts
Showing posts with label DM-V-VM. Show all posts

Wednesday, 6 August 2008

Kodama - a spirit of tree.

Some of you have probably read my post about Josh Smith and ViewModel coming to rescue people (WPF-addicted people, to be precise), just joking don't mind. In brief words, I wrote how ViewModel helped working with ComboBox or another Selector control to manage state of underlying CollectionView. After that I've generalized my thoughts, and there came a SelectorCollectionPresenter class, which made my sleep quiet. =) I'll publish code in the end as a bonus.


But now I want to write about the TreeView control, and how it can be united and simplified with ViewModel pattern. I was inspired a long time ago, when I read this article by Josh Smith, but had no time to work with WPF, solving other infrastructural problems, but I've got the idea stuck in my head.
And finally I got time to think about it and put it together in a reusable manner. As a result I've got a tree control with a spirit living in it. I named it Kodama, because kodama is a spirit from Japanese folklore, which is believed to live in trees. And the control itself was called KodamaView. As you might have already guessed, this spirit, which lives in my tree control, is nothing more than a ViewModel!

- he said ViewModel?

I want to warn everybody – I've just put together my thoughts on DM-V-VM pattern and Josh's fantastic ideas, so most of honors should go right to Josh!

KodamaView


KodamaView - is a UserControl, hosting a TreeView inside itself. In order to simulate TreeView's behavior, it inherits ITreeView interface, based on my IWPFView interface, and delegates all incoming calls to internal TreeView control.


TreeView simulating interface.


KodamaView control.


Control's xaml.

Kodama.

And now here are some words about Kodama.


Toriyama Sekien's illustration of a kodama appearing as an old man.

My Kodama (if it is allowed to say so) is an inheritor of ViewModel class, parameterized with ITreeView and IDataModelBase interfaces. The last one is made basic to be able to create Kodama with any derived DataModel class, because all of them embody this interface. DM is the source of data for the tree.



Every TreeViewItem gets its own ViewModel - a TreeViewItemViewModel.



TreeView is able to load child nodes "lazily", only when their parent node is expanded (I've borrowed the code from Josh's article, I hope he doesn't mind). All work on loading children is done in a LoadChildren method.



There is another one class in hierarchy - TreeViewItemViewModel`1. It has only one purpose to exist - to populate a typed Entity into the visual tree.



StructureTreeKodama is my example demonstrating this philosophy.




I remember, when I started the post, I've promised you a bonus. So here it is - SelectorCollectionPresenter class code. You can read some on details of it here.



Good luck!

Tuesday, 24 June 2008

WPF Presentation layer

I am about to stop blogging for next three weeks.

I'd like you to spend this time with pleasure and use so here is the candy: Presentation Layer.
This is a small framework to help develop desktop WPF applications. Mostly it is a DM-V-VM implementation with some other stuff I've blogged about.

And, finally, I am going to make a candy more yummy. I've included source codes for my WPF Wizard control as I've promissed some time ago.

Enjoy!

Friday, 6 June 2008

How Josh saved my day or the power of the Model side

May be I missed something but it was a challenge for me to maintain a following situation.

Imagine, for example, that you have an object with some property that can be chosen from some external list of values. How would you solve it? You'll, probably, put in UI some Selector control, say it would be a ComboBox, bound with list of available values. You would bind its SelectedItem property with underlying object's target property by means of OneWayToSource binding. Quite easy so far, isn't it? Just write ViewModel for this view that will publish this object and will keep all logic. Now let's make this example a little trickier. Imagine that you have to edit a list of said objects and you have to choose a unique value for every particular object. You see now that it is not so easy anymore? And to puzzle you completely picture yourself a Configuration Dialog that hosts your editing UI. This dialog has OK and cancel button and your objects' state must stay sync with what you do. Something like the following:

Don't be scared this UI is just for tests =).

I've written a number of posts about M-V-VM pattern, but in spite of was completely cumbered with this scenario. I do have an infrastructure to edit objects (I've written about it here), but in this case I was baffled. The problem was with this list of available values. To make it easier for understanding I'll introduce some classes.

The scenario is as follows: I have a number of visual addins (powered by Managed Add-Ins Framework) (I really should write about it, but I'll do it later) that I want to host in my UI. But they can be hosted only in the named Workspaces (a CAB's notion, it is not a WPF restriction it is my decision). You can see the model now. I've got AddInDescriptor objects that keep a name of containing workspace and addin token. This name can be set in Configuration Dialog by browsing and selecting one from available list. This dialog can commit or rollback changes and at next start it must show appropriate content.


descriptor class. just a DTO.


descriptor data template.


listbox item style.

The problem
looks like this: when I first set the name of containing workspace and then rollback and start again, combobox updates current item binding (AddInDescriptor.ContainingWorkspaceName property) with a valid empty workspace name and then explicitly sets the first item as current without update. This strange behavior violates all the logic written in a style's triggers. I tried to fix this broken behavior in a whole bunch of ways but neither of them worked.

And this is whe
n an idea dawned at me! I remembered a beautiful article written by WPF-rock star (of course it was Josh, who else?) about the simplest way to manage a TreeView in WPF. Here it is: http://www.codeproject.com/KB/WPF/TreeViewWithViewModel.aspx. I say this article is a MUST read.

And then I thought: "What is the difference? I have to do the same with ComboBox in my case.", and everything became clear.

I've created a AddInDescriptorPresenter class that held all the UI related logic. It is nothing more then a UI-proxy to the object and is intended to publish object- and UI-related properties. This class accepts a CollectionView (a built-in VM for collection) which a Combo is bound with.

AddIn descriptor presenter.

A list of these proxies is created and exposed by UI ViewModel that keeps a list of AddInDescriptors.

You might be interested what the TransactionalTune is.
TransactionalTune is a special data container, a volatile transaction manager based on Juval Lowy's fantastic article. You can read more here.
All this UI-proxy does is controlling the state of CollectionView that is synchronized with ComboBox.


AddInDescriptorPresenter code.

Template to render this presenter became a little bit easier.


AddInDescriptorPresenter data template.

I've spent a couple of days trying to solve this problem writing tons of different xamls and code-behinds, and it took me about an hour to make everything work correctly with the ViewModel!
You see now that it is powerful?

Good luck!

Tuesday, 8 April 2008

DataModel-View-ViewModel in WPF. Part 3 Example.

This is the last part on DM-V-VM pattern overview. In this part we'll write a simple WPF application built on this pattern.

DM-V-VM

Let's suppose that we have an object of class Foo that is provided by the SEModel class (parameterized with Foo and FooProvider types). It will be a demonstration of simplicity that SEModel gives - we don't have to write datamodel class, only provider class will be written.




All the logic is contained in a FooViewModel class. It is derived from ActionsViewModel as we'll have some actions triggers in UI (buttons). The actions are represented by two CommandModels - IncCommandModel and DecCommandModel. IncCommandModel increments Foo.Bar property when executed and DecCommandModel decrements it respectively. The DataModel is asked to refresh on View's Load event. DataModel will fetch data asyncronously and throw an event on UI thread as described in a first post
.

CommandModel classes implements logic for editing underlying data (Foo object) that is referenced in CommandParameter property of UI command triggers (objects that implement ICommandSource interface - Buttons in our example).


Now it is a view's turn.

In this example we won't use an IoC-container and will hardcode all dependecies in our classes. View creates ViewModel on it's Initialized event.



And keeping in mind that ViewModel sets itself to the DataContext property of View (window in our case) we know that all visual tree of our view will inherit VM in DataContext property. So just put a ContentControl in a view, bind it's Content property to VM and write a template to render VM.



The only evil SEModel can bring - is lack of ability to bind to it's Entity property. DataBinding just can't fetch the object even if all paths are accurate in 2 or more level templates. But this issue can be avoided easily - just put your object in View's resources in DataModelLoaded event in ViewModel and reference it in Binding via Source property.



This is how our application looks like:



Source for download: here.

Good luck!

PS: PnP group will finish their new project called - Prism, soon. It is intended to become CAB's replacement in developing LOB applications with WPF. Check for weekly drops here.

DataModel-View-ViewModel in WPF. Part 2 View and ViewModel.

This is the second part on my DataModel-View-ViewModel overview. In the previous part I was talking about DM classes which are intended to supply presentation layer that is composed of the View and ViewModel with data. Let's look at this View and ViewModel.

View

View is just a view (a xaml + codebehind class) and nothing more. It shouldn't keep any state or implement any logic operations except ones that relates to rendering.

VM doesn't "know" the view class and "speaks" with it through the IView interface. As I've mentioned earlier VM doesn't let you to switch UI framework without code review as ViewModel is tightly coupled with WPF-specific entities (such as commands), so for simplicity's sake I've promoted a IWPFView interface that consists of WPF-specific properties and events.



ViewModel

And at last main trinity's player. This class keeps all view related logic and state. My base VM class is parameterized vith view interface and it's descendant is parameterized with DM interface. Using CAB's IoC-container I resolve all of VM dependencies and inject it (VM) into View.



This classes have a bunch of useful virtual methods that are fired when View/DataModel set/unset events happen, in DataModel Loaded/ExceptionCatched events and View's Loaded/Unloaded. In a base class VM sets itself to a view's DataContext property, thus enabling it to update itself by DM, business objects and VM change events catching in databinding. So, speaking in Martin Fowler's words view in WPF is an ActiveView.


You can also find an ActionsViewModel on the diagram above. This class keeps a CommandModel objects list (very useful approach to wrap wpf command from Dan Crevier). For every command VM creates a command binding in a view automaticly.

ViewModel doesn't prohibit you from editing business object supplied by DM in UI and doesn't makes any validations of unedrlying data. So to avoid errors of this kind all of my objects are being edited in wizard UI (I've written a custom WPF control for it. I'll propably write about it later) that tracks object state and avoids saving invalid objects. But if you want to edit objects in your UI in a simple way you propably should read this article from Pete W.

That is all on View and ViewModel. In next part I'll assemble a simple example and (as I promised before) I'll include a sample code.

Good luck!

Saturday, 5 April 2008

DataModel-View-ViewModel in WPF. Part 1 DataModel.

All of my UIs are built on very powerful pattern called DataModel-View-ViewModel (DM-V-VM) that was first described by Dan Crevier. I've written a small "framework" (I better say set of classes) to enhance it to my needs.


We have chosen a WPF UI framework in conjuction with the Composite Application Block (CAB) and SmartClient Software Factory (SCSF) to be the foundation of the presentation layer for the project. CAB stimulates and actively using another two UI patterns Model-View-Controller (M-V-C) and Model-View-Presenter (M-V-P). So my set of classes is an extension to an existing infrastracture that uses some of the built-in CAB functionality, especialy IoC-container to resolve dependencies of my classes.

DM-V-VM pattern is a special case of another more brief UI pattern - M-V-P. Martin Fowler calls it the PresentationModel. There is one problem with this pattern - it is fantastic in WPF, but you won't be able to switch to another UI technology without rewriting some code (you can read some on this in Dr.WPF blog). And if it is an evil you can live with than this pattern will be the best choice. And may be it will become too complex to maintain your code when you will have more then 5 data sources. In this case I would recomend you to switch to the M-V-P pattern.

So let's go on.

DataModel(DM)

Classes that provide data (business objects). Their duty is to provide data in WPF-friendly way (at least to implement INotifyPropertyChanged). All the properties and some of methods should only be accessed from UI thread, and it is strongly recommended not to block the UI thread for long.
I think that DM classes (as they were described by Dan Crevier) perfectly fits SOA way of programming, being a data gateway from services to UI.
But services are not the only possible source of data, it can be anything - a file in a file system, for example. To make DM classes lossely-coupled with this different data sources there are providers system that is delegated to obtain data (a strategy by GoF).
A foundation for my DM classes is the Dan Crevier's implementation of DM-V-VM pattern so I shall concentrate on my enhancments instead of rewriting code here.
  1. The first thing to come is the base interface for DM classes with the couple of inherited generic interfaces that are narrows (or should I say precises) DM functionality by restricting Entity and Provider types.
  2. The second thing is the typed provider interface.


  3. Base DM class is the third thing. It contains a bunch of asyncronous methods (load complete notification, exception catched notification, etc.) plus a set of virtual methods to be overriden in descendant classes.


Invention of generic provider enabled me to write generic DM class that is parameterized with an entity type and typed provider (typed by entity type). I've called it SingleEntityModel. This class frees you from writing lots of DM descendants with the only duty to provide some Entity.




All the clients work with the DM objects through their interfaces as they are treated as a local services and can be injected in dependent code by an IoC-container.
That is all on DataModel, check for new parts.
Good luck!
PS: I will include code in a later parts.