Programatically add content or change size?

Aug 31, 2009 at 9:30 AM
Is there any way to programmatically add a "DockableContent" with a specified width to a blank ResizingPanel, or to change the size after added?  I am having a heck of a time and cannot figure it out...  Ideally, I would like an empty window when my application starts.  From there, the user will load a project using a menu, which will open up content panes based on settings stored in my project file from when they last saved the project (like Visual Studio), or at least a project pane docked on the right.  Open documents would be re-opened so it would be just like the last time they had the project open. I cannot figure out how to make this happen.  Every time I add a "DockableContent" it is set to size zero unless I anchor it to a side that already has a non-zero size content present.  It seems to me that "Show" would never want to display a zero-size element, what would be the purpose?  I can't find how to change the size after it is there either.
Let's take a simple example, where I want to starat with a document on the left and content on the right.  there will be two buttons to add documents and content respectively:
<Window x:Class="Test1.Window1"
    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="Window1" Height="408" Width="670">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="22"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <ToolBar Grid.Row="0">
            <Button Name="buttonDocument" Click="buttonDocument_Click">Document</Button>
            <Button Name="buttonContent" Click="buttonContent_Click">Content</Button>
        </ToolBar>
        <ad:DockingManager Name="dockManager" Grid.Row="1">
            <ad:ResizingPanel Name="rp1">
                <ad:DocumentPane Name="docp1">
                </ad:DocumentPane>
                <ad:DockablePane Name="dp1" ad:ResizingPanel.ResizeWidth="200">
                </ad:DockablePane>
            </ad:ResizingPanel>
        </ad:DockingManager>
    </Grid>
</Window>
public partial class Window1 : Window
{
	public Window1()
	{
		InitializeComponent();
		AddContent();
//			AddDocument();
	}

	public void AddContent()
	{
		DockableContent dc = new DockableContent();
		Label l = new Label();
		l.Content = "Hello, content!";
		dc.Content = l;
		//ResizingPanel.SetResizeWidth(dc, new GridLength(200));
		//dockManager.Show(dc, DockableContentState.Docked, AnchorStyle.Right);
		dockManager.Show(dc);
	}

	public void AddDocument()
	{
		DocumentContent dc = new DocumentContent();
		Label l = new Label();
		l.Content = "Hello, document!";
		dc.Content = l;
		dockManager.Show(dc);
	}

	private void buttonDocument_Click(object sender, RoutedEventArgs e)
	{
		AddDocument();
	}

	private void buttonContent_Click(object sender, RoutedEventArgs e)
	{
		AddContent();
	}
}

This actually starts off OK, with no document loaded and the content on the right.  This would be absolutely ideal if more added content appeared in the same DockablePane with tabs at the bottom.  However, then I can add documents, but when I add more content it appears with size 0 on the far rigtht, and I have to find the resize splitter to move it over.  Optimally it would appear in the same DockablePane as the existing content.
If I comment out the AddContent() in the constructor and use the button to call the exact same function, the content does not appear at all, I cannot even find a resize bar to let me view it.  However, if I then add a document, the resize bars appear on the right and I can drag them each out to view the ones I added.  I notice here that you can drag content into the document pane and view it along with documents, is that by design?
If I change the Show() call to use DockableContentState.Docked and AnchorStyle.Right, the content no longer shows up when started at all (I need to add a document to even see the resize bar), plus If I then add more contents they are hidden also.  If I then add more content, it also does not show up.  If I then add a document, the added content all shows up in one DockablePane with the correct width.  If I move that to another anchor, I can then see the zero-width content added by the call in the constructor.  Very confusing...
I found one way to hack and make it work...  I can start with a blank content declared in XAML, and then remove that blank content after I 'Show'.  Also I COULD setup all the resizing panels and panes I want ahead of time and do the layout save and restore, but aesthetically I would rather have that stuff not shown until they open a project.  Also, why not have the flexibility to change layouts programatically?  I can't even find how to make sizes different in the "Demo.xaml".  Why should all of the resize panels have to be the same size?
Feb 8, 2010 at 3:59 AM

Thank you for this, I'm trying to do the same thing. Your code helped me, but I'm sorry to say I can't help you with your question :(

Feb 9, 2010 at 4:10 PM

Hi,

first I've to say that a good starting point to understand how AvalonDock works is my tutorial on http://www.youdev.net/post/2008/09/25/AvalonDock-Tutorial.aspx.

Also maybe your're also interested in SharpDevelop 4 which integrates AvalonDock to build a VS-like workbench.

Regarding your question, I can't understand where you want to add the DockableContent. A DockableContent is usually added to a DockablePane. A DockablePane can be docked on a border, pinned or floated over the main window. In your case the AddContent() method, after created the DockableContent, should add it into a DockablePane (the same you defined in XAML or into a one created on the fly).

Maybe you already solved the problem, or I did'nt understand well what you mean, in any case I hope this helps.

Ado