Hidden DockableContent visible after loading WindowLayout

Jun 15, 2009 at 11:24 PM

Dear Avalon Team,

first of all great work! This is an excellent piece of software and my team and I are glad to use it.

here is our problem: After loading saved window layout, all DockableContent is visible even though it is marked as hidden.

Please find setup below.

 

If I hide all DockableContent with this.dockingManager.Hide(content); // where content is DockingContent

and afterwards try to show one of hidden contents I get following exception:

System.ArgumentOutOfRangeException occurred
  Message="Specified argument was out of the range of valid values.\r\nParameter name: index"
  Source="PresentationCore"
  ParamName="index"
  StackTrace:
       at System.Windows.Media.VisualCollection.get_Item(Int32 index)
       at System.Windows.Controls.UIElementCollection.get_Item(Int32 index)
       at AvalonDock.DockingManager.Anchor(Pane paneToAnchor, AnchorStyle anchor)
       at AvalonDock.DockingManager.Show(DockableContent content, DockableContentState desideredState, AnchorStyle desideredAnchor)
       at AvalonDock.DockingManager.Show(DockableContent content, DockableContentState desideredState)
       at AvalonDock.DockingManager.Show(DockableContent content)
       at BK.ENMIS.ApplicationFramework.MainForm.SetContentsVisibility(UserControl control, Boolean show) in C:\Projects\ENM2.4\Applications\ENM\InformationSystem\Frameworks\Minimal\MainForm.xaml.cs:line 261
  InnerException:

 

Thanks & Regards

Rale


Adding a new DockableContent

            // Create content
            DockableContent content = new DockableContent
            {
                Title = control.Title,
                Name = control.EnglishTitle,    // Make sure that name does not contain special chars
                Uid = uniqueID,
                Content = control
            };


            // Add content to pane
            this.dockablePane.Items.Add(content);


MainForm

<Window x:Class="My.MainForm"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:ad="clr-namespace:AvalonDock;assembly=AvalonDock"
    Title="My MainForm" Height="600" Width="800">
    <Window.Resources>
        <Image x:Key="ApplicationIcon" Source="ApplicationIcon.ico" />
        <Image x:Key="ConnectedIcon" Source="Icons/Database 16 n p.png" />
        <Image x:Key="DisconnectedIcon" Source="Icons/Delete Database 16 n p.png" />
    </Window.Resources>
    <DockPanel LastChildFill="True">
        <DockPanel.LayoutTransform>
            <ScaleTransform ScaleX="1" ScaleY="1"/>
        </DockPanel.LayoutTransform>
        <Menu DockPanel.Dock="Top" Name="menuStrip" />
        <ToolBar DockPanel.Dock="Top" Name="toolBar" />
        <StatusBar DockPanel.Dock="Bottom" Name="statusBar">
            <StatusBarItem Grid.Column="0" HorizontalAlignment="Left">
                <Image Height="16" Width="16" Name="toolStripConnectIcon" />
            </StatusBarItem>
            <Separator />
            <StatusBarItem Grid.Column="1" HorizontalAlignment="Left">
                <TextBlock Name="toolStripStatusLabel"></TextBlock>
            </StatusBarItem>
            <StatusBarItem HorizontalAlignment="Right">
                <ProgressBar Height="16" Width="100" Name="toolStripProgressBar" />
            </StatusBarItem>
        </StatusBar>
        <ContentControl x:Name="TestContainer">
            <ad:DockingManager x:Name="dockingManager">
                <ad:ResizingPanel>
                    <ad:DockablePane x:Name="dockablePane" />
                </ad:ResizingPanel>
            </ad:DockingManager>
        </ContentControl>
    </DockPanel>
</Window>


Saved Windowlayout

<DockingManager>
  <Hidden>
    <DockableContent Name="MyUserControl1" AutoHide="false" />
    <DockableContent Name="MyUserControl2" AutoHide="false" />
  </Hidden>
  <Windows />
</DockingManager>

Jun 16, 2009 at 8:38 AM

Hi,

I marked this as an issue, anyway the xaml is not correct. Your should avoid to use a resizepanel with only one child and much more important you must avoid to insert a dockablepane with no dockable content inside. Your xaml is equivalent to an empty dockingmanager.

Could you show me the initial xaml before hiding all contents?

 

thanks for using AvalonDock

Ado

Jun 16, 2009 at 9:15 AM

I think these rules and all the others (if there are any) should be put in some quick start guide.

Jun 16, 2009 at 9:39 AM

Hi Ado

thanks for the fast respond. Initial window layout can be found below.

@1) Reason that ResizingPanel is there as I was following example in AvalonDockDemo.Demo.xaml (well this was taken from 1.1 demo, don't know if you support this or have changed since). I will try without ResizingPanel.

@2) I'm not quite sure what do you mean by "avoid to insert a dockablepane with no dockable content inside". Does this refer to DockablePane when in ResizingPanel or DockingManager? Please see step Adding a new DockableContent for more detail. All DockableContent has content assigned before adding to DockablePane. DockablePane is defined in MainForm.xaml but removed when closing all windows (to avoid this I've put a check in AvalonDock.DockingManager.Hide() to return if content is null).

Thanks & Regards

Rale

 

Initial Windowlayout

<DockingManager>
  <ResizingPanel Orientation="Horizontal">
    <DockablePane ResizeWidth="0.2125" Anchor="Left">
      <DockableContent Name="MyUserControl1" AutoHide="false" />
    </DockablePane>
    <DockablePane Anchor="Left">
      <DockableContent Name="MyUserControl2" AutoHide="false" />
    </DockablePane>
  </ResizingPanel>
  <Hidden />
  <Windows />
</DockingManager>

Jun 16, 2009 at 10:18 AM

Sorry, but I can't follow you, can you explain better what your gui should work, I mean what you are trying to do.

Regarding DockablePane with no DockableContents inside i was referring to this error:

This xaml is not correct:

            <ad:DockingManager x:Name="dockingManager">
                <ad:ResizingPanel>
                    <ad:DockablePane x:Name="dockablePane" />
                </ad:ResizingPanel>
            </ad:DockingManager>

because you are creating a resizepanel with only one child (the DockablePane) and also you're creating a DockablePane that is empty (means with no children DockableContents).

The equivalent xaml is:

            <ad:DockingManager x:Name="dockingManager"/>

When you restore a layout from disk, (using for example the initial layout you just posted) avalondock recreate all the structures (ResizingPanels, DockablePanes/DockableContents) and associate it with the current actual contents (MyUserControl1,MyUserControl2). In your case before restoring the layout, MyUserControl1 and MyUserControl2 must be present into the xaml as children of dockingmanager.

For example starting from this xaml:

            <ad:DockingManager x:Name="dockingManager">
                    <ad:DockablePane x:Name="dockablePane" >
                        <ad:DockableContent x:Name="MyUserControl1"/>
                        <ad:DockableContent x:Name="MyUserControl2"/>
                     </ad:DockablePane>
            </ad:DockingManager>

you can call the dockingManager.RestoreLayout() with your initial xml layout. After that you should notice that all the dockablecontents are not visible (because so is specified into the xml layout). At that point you can show them calling the DockingManager.Show() method.

Hope this helps,

Ado