This project is read-only.

Prism/AvalonDock wrong DocumentPane instance...

Jul 12, 2011 at 4:18 PM
Hi all, im using Avalon Dock with Prism 4.0.
I have a module that can open multiple Instance of documents. So i thought the best way to do this would be to have them open in the DocumentPane whenever required.
In order to do this i've created an RegionAdapter for the DocumentPane and Hooked my region like shown in the XAML below (in Bold):

XAML Code:
    <!--The docking Manager display the terminal grid/ the tree view/ the 3d scene/ properties/etc-->
        <ad:DockingManager x:Name="dockManager" Grid.Row="1"
                           Loaded="dockManager_Loaded">
            <ad:ResizingPanel Orientation="Vertical">

                            <ad:DockablePane ad:ResizingPanel.ResizeHeight="0.25*">
<!--Some other panels-->
                    </ad:DockablePane>

                    <!--The 3D View-->
                    <ad:DocumentPane  prism:RegionManager.RegionName="{x:Static inf:RegionNames.ProjectInstanceRegion}" 
                                      
                                      x:Name="ProjectInstanceRegion">
                        <ad:DocumentContent Title="Some title" >

                        </ad:DocumentContent>

                    </ad:DocumentPane>

                    <ad:ResizingPanel	Orientation="Vertical"
											ad:ResizingPanel.ResizeWidth="0.25*">
                        <!--Properties Panel-->
                        <ad:DockablePane ad:ResizingPanel.ResizeHeight="0.5*">
                               <!--Some other panels-->
                        </ad:DockablePane>

                        <ad:DockablePane ad:ResizingPanel.ResizeHeight="0.5*">
                               <!--Some other panels-->
                         </ad:DockablePane>
                   
                    </ad:ResizingPanel>
                </ad:ResizingPanel>

                <ad:DockablePane ad:ResizingPanel.ResizeHeight="0.25*">
<!--Some other panels-->
                </ad:DockablePane>

            </ad:ResizingPanel>
        </ad:DockingManager>
The Region Adapater:
Imports Microsoft.Practices.Prism.Regions
Imports AvalonDock
Imports System.Collections.Specialized
Imports System.Windows.Controls.Primitives

Public Class AvalonRegionAdapter
    Inherits RegionAdapterBase(Of DocumentPane)

    Public Sub New(ByVal factory As IRegionBehaviorFactory)
        MyBase.New(factory)
    End Sub


    Protected Overrides Function CreateRegion() As Microsoft.Practices.Prism.Regions.IRegion
        Return New AllActiveRegion()
    End Function

    Protected Overrides Sub Adapt(region As Microsoft.Practices.Prism.Regions.IRegion, regionTarget As AvalonDock.DocumentPane)
        AddHandler region.Views.CollectionChanged, Sub(sender As [Object], e As NotifyCollectionChangedEventArgs)
                                                       OnViewsCollectionChanged(sender, e, region, regionTarget)
                                                   End Sub

    End Sub

    Private Sub OnViewsCollectionChanged(sender As Object, e As NotifyCollectionChangedEventArgs, region As IRegion, regionTarget As DocumentPane)
        If e.Action = NotifyCollectionChangedAction.Add Then
            'Add content panes for each associated view. 
            For Each item As Object In e.NewItems
                Dim view As UIElement = TryCast(item, UIElement)

                If view IsNot Nothing Then
                    Dim newContentPane As New DocumentContent()
                    newContentPane.Content = item
                    newContentPane.IsCloseable = True

                    'if associated view has metadata then apply it.
                    newContentPane.Title = view.[GetType]().ToString()

                    'When contentPane is closed remove the associated region 
                    AddHandler newContentPane.Closed, AddressOf OnClose
                    regionTarget.Items.Add(newContentPane)
                    newContentPane.Activate()
                End If
            Next
        Else

            If e.Action = NotifyCollectionChangedAction.Remove Then
            End If
        End If
    End Sub

    Private Sub OnClose(ByVal sender As Object, ByVal e As EventArgs)

        Dim t = False
    End Sub

End Class



I've configured correctly my RegionAdapter mapping in the bootstrapper and everything seem to be working fine, the RegionAdapter Collection changed get hit when i try to add my view but the problem is that doesnt seem to be using the right instance of the DocumentPane.

When i look at the DocumentPane (called regionTarget in the CollectionChanged Code) i dont see the DocumentContent Title="Some title".

So it looks like it's using a different instance of the documentpane than the one that should've been created.

 

Any ideas??

 

thanks.

 

 

Jul 13, 2011 at 11:00 AM

Do you use Unity of MEF ?

In both cases check they do not create uncontrolled instances, we had to fix this kind of problem problem using MEF ...

Bernard from Sofa, (AvalonDock in composite applications).

Jul 13, 2011 at 2:55 PM
Edited Jul 13, 2011 at 3:13 PM
 

Hi Bernard!

Im using unity.

Just maybe to complement, all my other regions get loaded and displayed correctly.

Also, if i try to use a TabControl instead (like in the XAML below) to display my possible documents it works fine...

 <ad:DocumentPane                                        x:Name="ProjectInstanceRegion">
                        <ad:DocumentContent Title="Some title" >

                            <TabControl prism:RegionManager.RegionName="{x:Static inf:RegionNames.ProjectInstanceRegion}">
                                <TabControl.ItemsPanel>
                                    <ItemsPanelTemplate>
                                        <Grid/>
                                    </ItemsPanelTemplate>
                                </TabControl.ItemsPanel>
                            </TabControl>
                        </ad:DocumentContent>
                    
                    </ad:DocumentPane>

But how would i check for uncontrolled instances? How should i fix it if i have any?

Thanks!

Jul 13, 2011 at 3:40 PM
Edited Jul 13, 2011 at 4:37 PM

<Not relevant>

Jul 13, 2011 at 4:36 PM

Ok i found my problem, it was completly my mistake :)

I realized that my "RestoredSaveLayoutPanel" was loaded on startup which is recreating the Panels and therefore conflicting with the reference stored in the Adapter.

Everything worked well when i removed the call to my Restory logic.

Thanks for assistance :)