DockSite and Caliburn.Micro

Docking/MDI for WPF Forum

Posted 12 years ago by David Buksbaum
Version: 11.2.0551
Avatar
Hello,

I have done some work to make Actipro's docking framework work with the Caliburn.Micro MVVM framework. However, in order to do so, I had to create a derived DockSite class so I can override PrepareContainerForItemOverride. Specifically, I am doing a model first approach using the binding (ToolItemsSource) to create my ViewModels. I then do Caliburn.Micro View location, bind the View to the View.Model, and then attach the created View to the element.Content property.

I want to know if this is valid or will it break anything else? I was going to set the Content property in the DockSiteViewModelBehavior (provided in the sample), but the tool window is created and the Content property already set. Seems a bit wasteful to create a default ContentControl and then override it. Further, I am not sure what is going on under the covers to ensure I wont break something else.

It seems that for better support of the MVVM pattern, it would be helpful to provide some means of my plugging in ViewModel and View look up functions. The container would call to my code with contextual information, and I can look it up from there. The current binding works well for locating the view model as a property on the parent view model, but having to use the datatemplates to map to the view hard codes my view / viewmodel relationship.

David

Comments (6)

Posted 12 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi David,

It sounds like you could use a DataTemplateSelector to dynamically select your DataTemplate. You would need to set the ContentTemplateSelector property on DocumentWindow/ToolWindow, using either an implicit Style or the DockSite.DocumentItemContainerStyle/ToolItemContainerStyle properties.


Actipro Software Support

Posted 12 years ago by David Buksbaum
Avatar
The problem is that using the Styles will bypass the Caliburn.Micro MVVM framework and have me wiring up my own view to view model binding. Specifically, I need the view to be created by the CM framework so that the appropriate bindings are completed, and the IOC gets its chance to inject the dependencies.

David
Posted 12 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi David,

I'm sorry but we are not familiar with Caliburn.Micro, as we only currently support Prism. But it sounds like overriding PrepareContainerForItemOverride is the best option. The DockSite should be similar to any other ItemsControl in this regard, so if there is a recommended approach for ListBox/etc then that should apply to our DockSite as well.


Actipro Software Support

Posted 12 years ago by David Buksbaum
Avatar
Hi,

The question is not how to support Caliburn.Micro, I have two ways developed at this time, but if overriding PrepareContainerForItemOverride() on the DockSite and setting the element.Content property would break anything in the DockSite. If not, then I have a working solution for supporting Caliburn.Micro (and probably anything else that needs to do a view lookup for View to ViewModel binding.

David
Posted 12 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi David,

Ok, I understand. Setting the Content property is fine in all but one situation. If your PrepareContainerForItemOverride set the Content property *before* calling our base PrepareContainerForItemOverride implementation *and* DockSite.ItemContainerRetentionMode was set to Wrapped. In this case, our PrepareContainerForItemOverride will set the Content property to a ContentControl that hosts the view-model. In this situation, our PrepareContainerForItemOverride would wipe out anything you set.

So as long as you call our PrepareContainerForItemOverride first, then set the Content everything is good. You may also want to make sure you don't set ItemContainerRetentionMode to Wrapped, as it would needlessly create instances of ContentControl.


Actipro Software Support

Posted 12 years ago by Chris Woodward
Avatar
David,

Do you mind sharing your code? I'm trying to do the same thing.

I've got this far

public class ViewInjectionDockSite : DockSite
{
    protected override void PrepareContainerForItemOverride(DockingWindow element, object item, DockingWindowItemType type)
        {
            ItemContainerRetentionMode = DockingWindowItemContainerRetentionMode.None;
            base.PrepareContainerForItemOverride(element, item, type);

            var view = ViewLocator.LocateForModel(item, null, null);
            ViewModelBinder.Bind(item, view, null);

            // This is workaround to set the title. 
            element.Title = ((Screen) item).DisplayName;
            element.Content = view;
        }
}
If I try

<Controls:ViewInjectionDockSite ToolItemsSource="{Binding ToolScreens}"/>
I get no ToolWindows showing even though the PrepareContainer override is hit for each view model.

It seems like I need to call DockingWindow.Activate() at some stage after it's registered with the dock site. Doing this in OnWindowRegistered works but I'd like to get at the view model to check for a ShowOnStartUp boolean and at that stage the DataContext is still null.

Do you know where I can hook into to do this, or even better, how to tell it to be active when added in the xaml?

I'd like to bind the title in the xaml too as I need the title to be a two-way binding for documents.

Edit: For reference if anyone is interested my full xaml is

<Controls:ViewInjectionDockSite
    ToolItemsSource="{Binding ToolScreens}"
    DocumentItemsSource="{Binding WorkspaceScreens}">
    <Docking:SplitContainer>
        <Docking:Workspace>
            <Docking:TabbedMdiHost>
            </Docking:TabbedMdiHost>
        </Docking:Workspace>
        <Docking:ToolWindowContainer>
        </Docking:ToolWindowContainer>
    </Docking:SplitContainer>
</Controls:ViewInjectionDockSite>
[Modified at 02/15/2012 07:16 PM]

[Modified at 02/15/2012 07:30 PM]
The latest build of this product (v24.1.1) was released 2 months ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.