[Version 2.0] Integrating with Caliburn.Micro

Jun 9, 2012 at 1:14 PM

Hi, I have an existing Caliburn.Micro application and I should integrate AvalonDock 2 into it. Googling around I found some solutions, but they all seem to refer to previous versions of this library. Essentially, the main VM is a shell derived from Conductor<IScreen>.Collection.OneActive, exposing an observable collection of Screen-derived VM's, and several properties representing single VM's. The collection represents a series of document-like panes while these properties are dockable, fixed panes. Now, I imagine I can simply bind the single panes to the UI using for each a LayoutAnchorable whose content is a ContentControl named as the corresponding VM property of the main shell: CM will locate and instantiate the view to be bound. Notice that I do not want to ditch CM and use AvalonDock templates for this: I need to just replace the UI of this existing CM-based application with another using AvalonDock. So, as for the documents instead, how should I bind the document manager DocumentsSource property to the collection exposed by the shell, which is a collection of VM's (not of views, of course)? Thanks!

Jun 10, 2012 at 8:29 PM

Hi,

Have a look at my example here

http://caliburnmicro.codeplex.com/workitem/218

It's a bit old now and so might not compile with current versions.

John

Jun 18, 2012 at 11:00 AM

Sorry for the late response, I had not noticed your reply. Thank you for the link, but as you wrote it is a bit old: I see it uses an ItemsControl bound to the viewmodels (screens) with an itemtemplate, but according to the new library design, with the DocumentsSource property, I'm inclined to think that this is no more the "intended" approach at least from the point of view of the library creator. Essentially, what I'm missing here is how to let CM do its magic for locating and instantiating the view to be used for each exposed VM (screen), given that I should bind to the library DocumentsSource. Perhaps some adapter? Anyone with CM experience might throw some light here? Thanks again!

Jun 18, 2012 at 2:18 PM

There is an example of the "adapter" that you refer to.
You need Custom Conventions for CM when using AvalonDock
J

Jul 18, 2012 at 9:55 PM

Thanks, and again sorry for the late response. I'm trying to use this sample but probably I do not know avalondock enough to modify the adapter so that it can work with the newer version. I tried to create an essential skeleton CM-based avalondock app downloadable from here: http://www.filedropper.com/docktest . Anyway the custom convention no more compiles, and I'm not sure about the new properties. If you run the application, which allows users to add new documents using a menu command, I can see that the doc VM's are created and added to my docs collection, and the view docking manager documents source reflects its change: but of course the view is not located, and I see a new tab with no title (as usual I'd like it to derive from the VM display name) and no content, except the name of the VM class (i.e. the result of calling ToString on it), nor the new document view is activated. If instead I simply add to the shell view an ItemsControl with name = DocumentsSource, CM works as expected and manages to locate the corresponding views: of course the problem lies in letting AvalonDock "talk" to CM. Could anyone give a hint or suggest good learning material about applied usages of this 2.0 library to this or other MVVM frameworks? Thanks again

Jul 25, 2012 at 4:42 AM
Edited Aug 3, 2012 at 11:54 AM

I have just finished upgrading my Gemini framework to AvalonDock 2.0, and I think it does exactly what you're trying to do:
https://github.com/tgjones/gemini

Gemini uses both AvalonDock 2.0 and Caliburn Micro.

Finding the right view for a given view model is easy-once-you-know-how, although it took me a while to find this solution:

 

<ad:DockingManager.LayoutItemTemplate>
	<DataTemplate>
		<ContentControl cal:View.Model="{Binding}" IsTabStop="False" />
	</DataTemplate>
</ad:DockingManager.LayoutItemTemplate>

 

Hope it helps - please let me know if you have any feedback.

Jul 25, 2012 at 11:53 AM

Thank you, that's awesome! I'll look further into your framework which seems very useful! It would be even better if you add some concept documentation and a NuGet package for it. Thanks again!

Jul 25, 2012 at 2:39 PM
Edited Jul 25, 2012 at 2:39 PM

Actually I've already created a NuGet package:
http://nuget.org/packages/GeminiWpf

I haven't publicised it yet because installation through NuGet isn't as easy as it should be. The Caliburn.Micro NuGet package (which is a dependency of GeminiWpf) installs some files that Gemini doesn't need or want. I need to figure out how to automatically delete those files, or not install them in the first place. After installing GeminiWpf, you'll want to delete everything apart from App.xaml and it's code-behind, and then make App.xaml look something like this:

<Application x:Class="Gemini.Demo.App"
			 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
			 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
			 xmlns:gemini="clr-namespace:Gemini;assembly=Gemini">
	<Application.Resources>
		<ResourceDictionary>
			<ResourceDictionary.MergedDictionaries>
				<ResourceDictionary>
					<gemini:AppBootstrapper x:Key="bootstrapper" />
				</ResourceDictionary>
			</ResourceDictionary.MergedDictionaries>
		</ResourceDictionary>
	</Application.Resources>
</Application>

I know that NuGet packages can make those kind of changes automatically, I just haven't set it up yet.

And yes, I really should write some concept documentation, but it's a chicken / egg situation - I don't want to spend time writing the documentation unless people are interested in using the framework, but people might not use the framework until there's better documentation :)

Anyway, let me know if you try it out.

Jul 26, 2012 at 12:08 PM

Hi, I don't know if it could be of any help in this case but, in the effort of providing easier support for frameworks like Caliburn,now the LayoutElement (and so LayoutAnchorable and LayoutDocument) derives from DependencyObject.

Ado

Jul 27, 2012 at 9:42 AM

I don't know the internals of CM, but as a novice user I can say the main problem in using it with this library is the one I posted about above, i.e. the connection of AD DocumentsSource with the viewmodels exposed as a collection property by CM. The template-based approach used in the AD samples is certainly useful when starting from scratch with this single library, but typically it will not be used when connecting it to a full-fledged MVVM framework like CM. Essentially in CM like in the majority of such frameworks you deal with viewmodels first: dockable panes typically correspond to a single VM exposed as a property of the main shell VM, and a collection of documents corresponds to a collection of VM's exposed as a property of the same shell VM. It is the framework responsability to locate the views for each VM and do the binding, which in the case of CM happens using naming conventions. As a library like AD will typically used for non-trivial applications where you have to deal with a modular approach, I suppose that most users would try using it in connection with their preferred MVVM framework, so it would be great taking into account their typical requisites when refining this library, and/or receive the contribution of skilled users of each of these frameworks to ensure an easy and effective usage of the library. In the case of CM, probably the a custom convention which connects the documents source with a collection property would suffice. Frameworks like Gemini sound great (and I encourage the author to write some concept docs, I know the dilemma, but it is worth it if you want it to be adopted by a large users base); but in some cases we just need to limit ourselves to the minimum number of 3rd party libraries, and especially for lighter projects it would be great to just plug in a class (in CM, a custom convention to adapt the documents source to the framework) to be able to leverage the full power of CM (or any other MVVM framework).