Re-attach children to ResizingPanel

Jun 1, 2010 at 11:15 AM

Hi. I have a docking manager and some elements inside. Here is the layout

 

<ad:DockingManager x:Name="dockingManager">
	<ad:ResizingPanel x:Name="resizingPanel">
		<ad:DockablePane x:Name="leftPane" ad:ResizingPanel.ResizeWidth="200">
			<ad:DockableContent x:Name="leftContent" Title="Left">
				...
			</ad:DockableContent>
		</ad:DockablePane>

		<ad:DocumentPane x:Name="middlePane">
			<ad:DockableContent x:Name="middleContent" Title="Middle">
				...
			</ad:DockableContent>
		</ad:DocumentPane>

		<ad:ResizingPanel x:Name="rightPanel" Orientation="Vertical" ad:ResizingPanel.ResizeWidth="200">
			<ad:DockablePane x:Name="topRigtPane">
				<ad:DockableContent x:Name="topRightContent" Title="TopRight">
					...
				</ad:DockableContent>
			</ad:DockablePane>

			<ad:DockablePane x:Name="bottomRightPane">
				<ad:DockableContent x:Name="bottomRightContent" Title="BottomRight">
					...
				</ad:DockableContent>
			</ad:DockablePane>
		</ad:ResizingPanel>
	</ad:ResizingPanel>
</ad:DockingManager>

 

When first displayed, I want all the panes to be hidden, so I do this in the handler for Loaded event on my top control:

 

leftContent.IsCloseable = true;
dockingManager.Hide(leftContent);

middleContent.IsCloseable = true;
dockingManager.Hide(middleContent);

topRightContent.IsCloseable = true;
dockingManager.Hide(topRightContent);

bottomRightContent.IsCloseable = true;
dockingManager.Hide(bottomRightContent);

Now, when something happens I want to show the panes. I wrote this code:

 

leftContent.IsCloseable = false;
dockingManager.Show(leftContent, DockableContentState.Docked);

middleContent.IsCloseable = false;
dockingManager.Show(middleContent, DockableContentState.Document);

topRightContent.IsCloseable = false;
dockingManager.Show(topRightContent, DockableContentState.Docked);

bottomRightContent.IsCloseable = false;
dockingManager.Show(bottomRightContent, DockableContentState.Docked);

The problem is this. I noticed that after doing Hide() on something, it is removed from the children list of its parent ResizingPanel. So, for instance, here I hide everything, so the two ResizingPanels involved have 0 children afterwards. But when I do Show(), the children are not re-attached. And this breaks the layout (for example the topRightContent and bottomRightContent are not shown vertically, but horizontally one next to the other, since they are no longer children for the rightPanel that has Vertical orientation). So how can I fix? Or if you know of a better way to do what I intend.

 

Hope I was explicit enough. Thanks.

Jun 1, 2010 at 12:17 PM
HI,
I suppose you're using version 1.2. With that version the best way to achive what you're looking for is to use layout serialization.
When your application starts load a layout with all contents hidden, than, when you prefer, just load another layout with all contents visible and right positioned.
Layout can be saved with SaveLayout() and restored with RestoreLayout().
Version 1.3 better handles cases like your, because it remembers position of contents.
Hope to be helpful!
Ado
From: [email removed]
Sent: Tuesday, June 01, 2010 12:15 PM
To: [email removed]
Subject: Re-attach children to ResizingPanel [AvalonDock:214556]

From: JohnQuest

Hi. I have a docking manager and some elements inside. Here is the layout

<ad:DockingManager x:Name="dockingManager">
	<ad:ResizingPanel x:Name="resizingPanel">
		<ad:DockablePane x:Name="leftPane" ad:ResizingPanel.ResizeWidth="200">
			<ad:DockableContent x:Name="leftContent" Title="Left">
				...
			</ad:DockableContent>
		</ad:DockablePane>

		<ad:DocumentPane x:Name="middlePane">
			<ad:DockableContent x:Name="middleContent" Title="Middle">
				...
			</ad:DockableContent>
		</ad:DocumentPane>

		<ad:ResizingPanel x:Name="rightPanel" Orientation="Vertical" ad:ResizingPanel.ResizeWidth="200">
			<ad:DockablePane x:Name="topRigtPane">
				<ad:DockableContent x:Name="topRightContent" Title="TopRight">
					...
				</ad:DockableContent>
			</ad:DockablePane>

			<ad:DockablePane x:Name="bottomRightPane">
				<ad:DockableContent x:Name="bottomRightContent" Title="BottomRight">
					...
				</ad:DockableContent>
			</ad:DockablePane>
		</ad:ResizingPanel>
	</ad:ResizingPanel>
</ad:DockingManager>

When first displayed, I want all the panes to be hidden, so I do this in the handler for Loaded event on my top control:

leftContent.IsCloseable = true;
dockingManager.Hide(leftContent);

middleContent.IsCloseable = true;
dockingManager.Hide(middleContent);

topRightContent.IsCloseable = true;
dockingManager.Hide(topRightContent);

bottomRightContent.IsCloseable = true;
dockingManager.Hide(bottomRightContent);

Now, when something happens I want to show the panes. I wrote this code:

leftContent.IsCloseable = false;
dockingManager.Show(leftContent, DockableContentState.Docked);

middleContent.IsCloseable = false;
dockingManager.Show(middleContent, DockableContentState.Document);

topRightContent.IsCloseable = false;
dockingManager.Show(topRightContent, DockableContentState.Docked);

bottomRightContent.IsCloseable = false;
dockingManager.Show(bottomRightContent, DockableContentState.Docked);

The problem is this. I noticed that after doing Hide() on something, it is removed from the children list of its parent ResizingPanel. So, for instance, here I hide everything, so the two ResizingPanels involved have 0 children afterwards. But when I do Show(), the children are not re-attached. And this breaks the layout (for example the topRightContent and bottomRightContent are not shown vertically, but horizontally one next to the other, since they are no longer children for the rightPanel that has Vertical orientation). So how can I fix? Or if you know of a better way to do what I intend.

Hope I was explicit enough. Thanks.

Jun 1, 2010 at 12:56 PM
Edited Jun 1, 2010 at 2:43 PM

The problem is that SaveLayout() does not work for me as I'd like, or I'm doing something wrong. So I want to save the initial layout, which is ok, before hiding anything. If I simply save in the Window's constructor, it gives an error: "Unable to serialize docking layout while DockingManager control is unloaded". If I save it in the handler for Loaded event, I get an empty file, it doesn't save anything, although everything seems fine the controls have all properties set, so I don't know what could be wrong.

Jun 1, 2010 at 1:18 PM

well, I think you should start your application without any code bihind (i.e. without hide all contents), when everything started (i.e. dockingmanager is loaded), hide all contents clicking on the hide button of each pane. After this save the layout (maybe you can add a temp button somewhere which calls the SaveLayout() method). than restart the application without loading any layout file. save again the layout now with all contets show.

You should then have two files, one with all contents hidden and one with all contents shown. (always load a layout when dockingmanager is loaded i.e. on the dockngmanager.loaded event handler)

Ado

Jun 1, 2010 at 2:45 PM

Thanks, it worked. I combined restoring the layout from xml with some manual hiding, and that did the job. Thanks again.