AvalonDock region adapters: incomplete?

Feb 19, 2010 at 9:02 AM

Hi,
First of all thanks to Markus Raufer for creating these adapters.
I've just started looking at the region adapters for AvalonDock by playing with the AvalonDockRegionAdapterSample.
I have a few queries:

1. NotifyCollectionChangedAction events
The adapters only hook up to the NotifyCollectionChangedAction.Add event, not the remove event. To see what’s going on I’ve added more views so that there are now 2 content items in each pane. I then added in the code to the adapters to hook up the NotifyCollectionChangedAction.Remove event. I then dragged content from one pane to the other expecting to see the Remove event firing but it doesn’t.
What this means is that even though content has been added to the correct regions initially, by the time one has dragged around a few controls, the regions are no longer in sync.
I assume one would somehow need to hook into add/remove and/or drag/drop events on the actual controls to keep the regions in sync. Is that right?
Is it possible to use this region adapter pattern to fully abstract away the AvalonDock docking framework?


2. Creating new controls on the fly
Once one has a docking framework one will need to create new controls at runtime and dock them into the appropriate panes.
To test out how this might work I added a button to the UI to create a new DockableContent - when the button is clicked, this code executes:
...
var view = _container.Resolve<DockableView>();
IRegion leftRegion = _regionManager.Regions[RegionNames.LeftRegion];
leftRegion.Add(view);
...

Sure enough the view gets added to the region and appears in the UI.

The way I have done this is for the button to execute a Command that on a simple ViewModel that is wired up to the view:

    public class DockableViewModel
    {
        private readonly IEventAggregator _eventAggregator;

        public ICommand CreateViewCommand { get; private set; }

        public DockableViewModel(IEventAggregator eventAggregator)
        {
            _eventAggregator = eventAggregator;
            CreateViewCommand = new DelegateCommand<object>(obj => CreateNewView());
        }

        private void CreateNewView()
        {
            _eventAggregator.GetEvent<CreateViewEvent>().Publish(null);
        }
    }

The command publishes an event.
The module subscribes to the event and creates the view (some code omitted for clarity):

    public class MainModule : IModule
    {
    ...
        public MainModule(IUnityContainer container, IRegionManager regionManager, IEventAggregator eventAggregator)
        {
            _container = container;
            _regionManager = regionManager;
            _eventAggregator = eventAggregator;

            _eventAggregator.GetEvent<CreateViewEvent>().Subscribe(CreateView);
        }

        private void CreateView(object obj)
        {
            var view = _container.Resolve<DockableView>();
            var vm = _container.Resolve<DockableViewModel>();
            view.DataContext = vm;

            IRegion leftRegion = _regionManager.Regions[RegionNames.LeftRegion];
            leftRegion.Add(view);
        }
    ...
    }

This works initially but then stops working: the command fires, the event is published, but the module never gets it – possibly because the module has been garbage collected.
I’m pretty sure that I should not be creating the new view in the module but my reasoning was that the module already knows about views and regions so it would be good to do it there.
I’ve had a brief look at Presenters and controllers but I’m loathed to add yet more indirection into the app at this stage.

What is the accepted way of creating a new view while at the same time ensuring that the viewModel does not know anything about views?

I’m a novice when it comes to region adapters but I’m trying to understand how they should work as I need to write some for some other third party controls.

Thanks very much.
Regards
Michael


Michael Mayne
RBS Sempra Energy Trading Holdings Ltd
155 Bishopsgate, London. EC2M 3TZ
Mobile: +44 (0) 7971 688 186

Coordinator
Feb 19, 2010 at 11:48 AM

Hi,

You posted this in the wrong place :) You need Composite WPF Contrib...

Aelij.

Feb 21, 2010 at 8:37 AM

Oops. Thanks.