Friday, October 26, 2012

Sacha Barber shares his WPF/RavenDB/MVVM Diagram Designer application

CodeProject - MVVM Diagram Designer



A while back a user called "sucram (real name Marcus)"  posted a series of articles here about how to create a diagram designer using WPF. Sucrams original links are as follows:

I remember being truly blown away by this series of articles, as they showed you how to do the following things:

  • Toolbox
  • Drag and Drop
  • Rubber band selection using Adorners
  • Resizing items using Adorners
  • Rotating items using Adorners
  • Connecting items
  • Scrollable designer surface, complete with zoombox

WOW that sounds fantastic, sounds exactly like the sort of things you would need to create a fully functional diagram designer. Well Yeah, its was and still is, but........the thing is I have used WPF a lot, and trying to use the code attached to sucrams series of article in WPF just wasn't that great. He had taken a very control centric view, in that everything was geared around adding new controls and supplying static styles for said controls.

In reality it was more like working with a Win Forms application. Not that there is anything wrong with that, and I really truly do not mean to sound ungrateful, as that could not be further from the truth, without that original series of articles it would have taken me a lot longer to come up with a working diagram designer that I was happy with. So for that I am truly grateful, thanks sucram you rock.

Anyway as I say sucrams original codebase took a very control centric point of view, and added controls using code behind, and held collections of items directly in the diagram surface control. As I say if that is what you want cool, however, it was not what I wanted. What I wanted was

  • All of the features of curams original code (actually I didn't want any rotating of items, or resizing of items)
  • A more MVVM driven approach, you know allow data binding of items, delete of items via ICommand etc. etc.
  • Allow me to control the creation of an entire diagram from within a single ViewModel
  • Allow for complex objects to be added to the diagram i.e. ViewModels that I could style using DataTemplate(s). Sucrams original code only allowed simply strings to be used as a DataContext which would control what ImageSource an Image would use to show for a diagram item. I needed my items to be quite rich and allow popups to be shown and associated with the diagram item, such that the data related to the diagram item could be manipulated
  • Allow me to save the diagram to some backing store
  • Allow me to load a previously saved diagram from some backing store

To this end I have pretty much completely re-written sucrams original code, I think there is probably about 2 classes that stayed the same, there is now more code, a lot more, however from an end user experience, I think it is now dead easy to control the creation of diagrams from a centralized ViewModel, which allows a diagram to be created via well known WPF paradigms like Binding/DataTemplating.

For example this is how the attached DemoApp code creates a simple diagram that is shown when you first run the DemoApp:


What Does It Look Like

This is quite interesting, as if you look at the screen shot below and compare that to the final article that sucram produces you probably won't see any difference, which as I previously stated was intentional. I think sucram really nailed it, I just wanted a more WPF style codebase, one that supported Binding etc. etc., so yeah I must admit you could easily look at this screen shot and think "Bah humbug......this is exactly the same", well yes visually speaking I guess it is, however the code is very very different, and the way in which you work with the diagram is very different. Anyway enough chat here is a screen shot.



This project is a demonstration project, and is a good example of how to create your own diagram designer. It is a fully functioning demo, and also demonstrates persisting/hydrating using RavenDB which is a NoSQL document database (as I could not be bothered writing loads of SQL)

Persistence common classes, used by DemoApp

I decided to use RavenDB for persistence which is a NoSQL database, that allows raw C# objects to be stored. I decided to do this, as I really couldn't be bothered to create ALL the SQL to save/hydrate diagrams, and I just wanted to get something up an running ASAP
Though if you use SQL server/MySQL etc. etc., it should be pretty easy to create the stored procedures/data access layer that talks to your preferred SQL database.

This project contains the core classes that are needed to create a diagram in WPF

How Do I Use It In My Own Applications

This section will talk you through how to create a diagram in your own application. It assumes the following

  • That you want to use WPF things like Binding/DataTemplating/MVVM
  • You actually want to persist / hydrate diagrams to some backing store (Like I say I chose to use RavenDB which is a no sql document database, but if this is not for you, it should be pretty easy for you to craft your own data access layer talking to your preferred SQL backend)

If you want to create your own MVVM style diagram designer, I have broken it down into 7 easy steps, as long as you follow these 7 steps to the letter you should be just fine. There is also a working example of these 7 steps by way of the attached DemoApp project code, so you can examine that whilst reading this text, so hopefully you will be ok.

Use It Step 1 : Creating The Raw XAML


Have you clicked through yet? Have you seen the depth and how long this article is? Yeah, wow.

I dig that he used RavenDB. I've been following that product but never used it (or think I've seen in used in a sample/demo I've downloaded). Then of course there's the MVVM goodness and everything else he's showing off. This should keep you code-geeking for a while...:)

No comments: