Prism/MEF + AvalonDock 2

Topics: Prism v4 - WPF 4
May 15, 2013 at 5:54 PM
Edited May 15, 2013 at 6:26 PM
Hi,
I'm trying to build Visual Studio like interface for my LOB application which is based on Prism 4 and MEF. so i used the following region adapters as per sample called Central :
1-AnchorableRegionAdapter
[Export(typeof(AnchorableRegionAdapter))]
    [PartCreationPolicy(CreationPolicy.NonShared)]
    public class AnchorableRegionAdapter : RegionAdapterBase<LayoutAnchorable>
    {
        [ImportingConstructor]
        public AnchorableRegionAdapter(IRegionBehaviorFactory regionBehaviorFactory)
            : base(regionBehaviorFactory)
        {
        }

        protected override void Adapt(IRegion region, LayoutAnchorable regionTarget)
        {
            if (regionTarget == null)
                throw new ArgumentNullException("regionTarget");

            if (regionTarget.Content != null)
            {
                throw new InvalidOperationException();
            }

            region.ActiveViews.CollectionChanged += delegate
            {
                regionTarget.Content = region.ActiveViews.FirstOrDefault();
            };

            region.Views.CollectionChanged +=
                (sender, e) =>
                {
                    if (e.Action == NotifyCollectionChangedAction.Add && region.ActiveViews.Count() == 0)
                    {
                        region.Activate(e.NewItems[0]);
                    }
                };
        }

        protected override IRegion CreateRegion()
        {
            return new SingleActiveRegion();
        }
    }
2-DocumentRegionAdapter
[Export(typeof(DocumentRegionAdapter))]
    [PartCreationPolicy(CreationPolicy.NonShared)]
    public class DocumentRegionAdapter : RegionAdapterBase<LayoutDocument>
    {
        [ImportingConstructor]
        public DocumentRegionAdapter(IRegionBehaviorFactory regionBehaviorFactory)
            : base(regionBehaviorFactory)
        {
        }

        protected override void Adapt(IRegion region, LayoutDocument regionTarget)
        {
            if (regionTarget == null)
                throw new ArgumentNullException("regionTarget");

            if (regionTarget.Content != null)
            {
                throw new InvalidOperationException();
            }

            region.ActiveViews.CollectionChanged += delegate
            {
                regionTarget.Content = region.ActiveViews.FirstOrDefault();
            };

            region.Views.CollectionChanged +=
                (sender, e) =>
                {
                    if (e.Action == NotifyCollectionChangedAction.Add && region.ActiveViews.Count() == 0)
                    {
                        region.Activate(e.NewItems[0]);
                    }
                };
        }

        protected override IRegion CreateRegion()
        {
            return new SingleActiveRegion();
        }
3-AvalonDockRegion
[Export(typeof(AvalonDockRegion))]
    public class AvalonDockRegion : DependencyObject
    {
        #region Name

        /// <summary>
        /// Name Attached Dependency Property
        /// </summary>
        public static readonly DependencyProperty NameProperty =
            DependencyProperty.RegisterAttached("Name", typeof(string), typeof(AvalonDockRegion),
                new FrameworkPropertyMetadata((string)null,
                    new PropertyChangedCallback(OnNameChanged)));

        /// <summary>
        /// Gets the Name property.  This dependency property
        /// indicates the region name of the layout item.
        /// </summary>
        public static string GetName(DependencyObject d)
        {
            return (string)d.GetValue(NameProperty);
        }

        /// <summary>
        /// Sets the Name property.  This dependency property
        /// indicates the region name of the layout item.
        /// </summary>
        public static void SetName(DependencyObject d, string value)
        {
            d.SetValue(NameProperty, value);
        }

        /// <summary>
        /// Handles changes to the Name property.
        /// </summary>
        private static void OnNameChanged(DependencyObject s, DependencyPropertyChangedEventArgs e)
        {
            CreateRegion(s, (string)e.NewValue);
        }

        #endregion Name

        private static void CreateRegion(object element, string regionName)
        {
            if (element == null)
                throw new ArgumentNullException("element");

            //If I'm in design mode the main window is not set
            if (Application.Current == null ||
                Application.Current.MainWindow == null)
                return;

            try
            {
                if (ServiceLocator.Current == null)
                    return;

                // Build the region
                var mappings = ServiceLocator.Current.GetInstance<RegionAdapterMappings>();
                if (mappings == null)
                    return;
                IRegionAdapter regionAdapter = mappings.GetMapping(element.GetType());
                if (regionAdapter == null)
                    return;

                regionAdapter.Initialize(element, regionName);
            }
            catch (Exception ex)
            {
                throw new RegionCreationException(string.Format("Unable to create region {0}", regionName), ex);
            }
        }
4-DockingManagerRegionAdapter
 [Export(typeof(DockingManagerRegionAdapter))]
    [PartCreationPolicy(CreationPolicy.NonShared)]
    public class DockingManagerRegionAdapter : RegionAdapterBase<DockingManager>
    {
        [ImportingConstructor]
        public DockingManagerRegionAdapter(IRegionBehaviorFactory regionBehaviorFactory)
            : base(regionBehaviorFactory)
        {
        }

        protected override void Adapt(IRegion region, DockingManager regionTarget)
        {
        }

        protected override IRegion CreateRegion()
        {
            return new Region();
        }

        protected override void AttachBehaviors(IRegion region, DockingManager regionTarget)
        {
            if (region == null)
                throw new System.ArgumentNullException("region");

            // Add the behavior that syncs the items source items with the rest of the items
            region.Behaviors.Add(DockingManagerDocumentsSourceSyncBehavior.BehaviorKey, new DockingManagerDocumentsSourceSyncBehavior
            {
                HostControl = regionTarget
            });

            base.AttachBehaviors(region, regionTarget);
        }
and Here is the part of XAML of my ShellWindow that contains AvalonDock:
<avalonDock:DockingManager x:Name="dockingManager">
            <avalonDock:LayoutRoot>
                <avalonDock:LayoutPanel Orientation="Horizontal">
                    <!--Control Panel-->
                    <avalonDock:LayoutAnchorablePaneGroup DockWidth="150" Orientation="Vertical">
                        <avalonDock:LayoutAnchorablePane>
                            <avalonDock:LayoutAnchorable Title="Systems"  regAdapters:AvalonDockRegion.Name="{x:Static inf:RegionNames.SubsystemRegion}">
                                <!--<TextBox/>-->
                            </avalonDock:LayoutAnchorable>
                            <avalonDock:LayoutAnchorable Title="Piping" regAdapters:AvalonDockRegion.Name="{x:Static inf:RegionNames.TestPackRegion}">
                                <!--<TextBox/>-->
                            </avalonDock:LayoutAnchorable>
                            <avalonDock:LayoutAnchorable Title="Equipment" regAdapters:AvalonDockRegion.Name="{x:Static inf:RegionNames.EquipmentListRegion}">
                                <!--<TextBox/>-->
                            </avalonDock:LayoutAnchorable>
                        </avalonDock:LayoutAnchorablePane>
                        <avalonDock:LayoutAnchorablePane>
                            <avalonDock:LayoutAnchorable Title="Tool 3">
                             </avalonDock:LayoutAnchorable>
                            <avalonDock:LayoutAnchorable Title="Tool 4">
                            </avalonDock:LayoutAnchorable>
                        </avalonDock:LayoutAnchorablePane>
                    </avalonDock:LayoutAnchorablePaneGroup>
                    <!--Main Pane-->
                    <avalonDock:LayoutDocumentPane >
                                                <avalonDock:LayoutDocument regAdapters:AvalonDockRegion.Name="{x:Static inf:RegionNames.MainRegion}"/>

                    </avalonDock:LayoutDocumentPane>
                    <!--Auxilary Panes-->
                    <avalonDock:LayoutAnchorablePaneGroup DockWidth="150" Orientation="Vertical">
                        <avalonDock:LayoutAnchorablePane>
                            <avalonDock:LayoutAnchorable Title="Tool 1">
                            </avalonDock:LayoutAnchorable>
                            <avalonDock:LayoutAnchorable Title="Tool 2">
                            </avalonDock:LayoutAnchorable>
                        </avalonDock:LayoutAnchorablePane>
                        <avalonDock:LayoutAnchorablePane>
                            <avalonDock:LayoutAnchorable Title="Tool 3">
                                
                            </avalonDock:LayoutAnchorable>
                            <avalonDock:LayoutAnchorable Title="Tool 4">
                            </avalonDock:LayoutAnchorable>
                        </avalonDock
and here is the override of RegionAdapterMappings in the Bootstrapper

please see next because it is limited by 1000 letter
May 15, 2013 at 5:57 PM
Edited May 15, 2013 at 6:34 PM
 protected override RegionAdapterMappings ConfigureRegionAdapterMappings()
        {
            base.ConfigureRegionAdapterMappings();

            var regionAdapterMappings = ServiceLocator.Current.GetInstance<RegionAdapterMappings>();
            if (regionAdapterMappings != null)
            {
                regionAdapterMappings.RegisterMapping(typeof(DockingManager),
                        ServiceLocator.Current.GetInstance<DockingManagerRegionAdapter>());
                regionAdapterMappings.RegisterMapping(typeof(LayoutAnchorable),
                        ServiceLocator.Current.GetInstance<AnchorableRegionAdapter>());
                regionAdapterMappings.RegisterMapping(typeof(LayoutDocument),
                        ServiceLocator.Current.GetInstance<DocumentRegionAdapter>());
            }

            return regionAdapterMappings;
        }
Now when i run i get this exception:
Developer
May 15, 2013 at 9:12 PM
Hi jivara,

It seems that the exception message was not posted. Please, edit the post to include it so that we can help you with it. Also, it would be helpful if you could also provide us a description of the error you are experiencing, as well as which behavior or component is throwing the exception.

Regards,

Damian Cherubini
http://blogs.southworks.net/dcherubini
Jun 1, 2013 at 12:34 PM
Hi,

Did you get it working? if yes the can you please share the sample app code. I am also evaluating AvalongDoc for building LOB apps where your each view will load as tab in the document pane.

Thanks and regards,
Milind Yande