Dynamically Adding Controls to the DockablePane

Oct 6, 2009 at 7:13 AM

This is my first look at anything WPF ( so please excuse any ignorance that is to follow )..

I am trying to dynamically add controls into a dockable pane. My thought was to set up something like this with a named DockablePane = "PluginPane"

<ad:DockingManager x:Name="dockManager">
   <ad:ResizingPanel Orientation="Vertical">
      <ad:ResizingPanel Orientation="Horizontal" > 
         
          <ad:DockablePane Name="PluginPane">
          </ad:DockablePane>

      </ad:ResizingPanel>
   </ad:ResizingPanel>
</ad:DockingManager>
So that in psuedo-code I could do something like this :
AvalonDock.DockableContent theContent = new AvalonDock.DockableContent();      
theContent.Title = "Some Title";
theContent.Children.Add( new Stackingit.CustomControl() );
PluginPane.Children.Add(theContent);
But there is no obvious (enter lack of any WPF knowledge?) Children.Add() for each of these as I have seen a standard container examples.
What is the correct way to do this ?
Thanks

 

Oct 6, 2009 at 11:29 AM

In the mean time I have discoverd MEF and CustomControls to help me out. So my contanier window look like this:

<Window x:Class="Stackingit.LoadFromPlugins.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="300" Width="300">
    <Grid>
      <ad:DockingManager x:Name="dockManager">
        <ad:ResizingPanel Orientation="Vertical">
          <ad:ResizingPanel Orientation="Horizontal" Name="PluginPoint" >
         
          </ad:ResizingPanel>   
        </ad:ResizingPanel>
      </ad:DockingManager>
    </Grid>
</Window>

 and I just define a custom control with the DocakablePane definition

<UserControl x:Class="Stackingit.WpfControlLibrary1.UserControl1"
    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">

  <ad:DockablePane>
    <ad:DockableContent Title="ExternalText">
      <TextBlock Text="ExternalText" Name="ExternalMyText"/>              
    </ad:DockableContent>
    <ad:DockableContent>
      <Button Content="EButon" Click="Button_Click"/>    
    </ad:DockableContent> 
  </ad:DockablePane>
    
</UserControl>

And then in the containig app I  add the childern honouring the IDebugPlugin export to the PluginPonit parent - where GetContent returns a UIElement

      foreach (IDebugPlugin debug in DebugPlugins)
      {               
        PluginPoint.Children.Add( debug.GetContent() );
      }

But there must be a better way than having to get your plugins to know that they are dockable - so please offer any advice.

Thanks

Oct 6, 2009 at 12:18 PM

DockablePane is an ItemsControl so you should use the Items property to a child DockableContent.

Anyway you should avoid to define by design a empty DockablePane. My advice is to create only a DockingManager with an internal DocumentPane.

     <ad:DockingManager x:Name="dockManager">
        <ad:DocumentPane/>
      </ad:DockingManager>

then use the DockingManager.Show(DockableContent) to show contents at desidered location.

For a short tutorial on AvalonDock please refer to http://www.youdev.net/post/2008/09/25/AvalonDock-Tutorial.aspx

For an advanced example of Addin pattern with AD, you could download the SharpDevelop 4.0 sources.

Ado