In this article I would to show a new feature that is present in AvalonDock from version 1.2.2515 that could be very useful for who is trying to integrate AvalonDock in WPF Composite Framework (aka PRISM).
Until build 2515 the only way to add a document content in AvalonDock docking manager was to take a document pane container and use its Items property. The following code shows how to add 5 documents to AvalonDock at runtime:
while (i < 5)
{
DemoDocument doc =
new DemoDocument();
doc.Title =
"Document " + i;
doc.InfoTip =
"Info tipo for " + doc.Title;
doc.ContentTypeDescription =
"Sample document";
//Add the new document to a DocumentPane (in this case create in XAML)
_documentsHost.Items.Add(doc);
i++;
}
The problem with this approach is that documents are internally managed by AvalonDock so that, for example, if user drag a document to an other pane, automatically AvalonDock remove it from the old container pane adding it to the new one. The result is that you couldn’t use the property DocumentPane.ItemsSource.
To overcome this problem I’ve created a new property for the DockingManager object called DocumentsSource.
As the name suggest, this property can be used just like the ItemsControl.ItemsSource property and it’s intended to refer to a DocumentContent collection.
Thanks to this property one can attach a custom collection of documents to AvalonDock:
<Window
x:Class="AvalonDockTest.Window4"
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="Text Document Source" Height="600" Width="800" >
<DockPanel>
<ToolBar DockPanel.
Dock="Top">
<Button Content="Add Documents" Click="Button_Click"/>
</ToolBar>
<ad:DockingManager x:Name="dockingManager" Loaded="dockingManager_Loaded"
DocumentsSource="{Binding Path=MyDocs}" RequestDocumentClose="dockingManager_RequestDocumentClose">
<ad:DocumentPane x:Name="_documentHost" />
</ad:DockingManager>
</DockPanel>
</Window>
In the above code a DockingManager object is create just under a toolbar containing a dummy button.
Inside you can see a document pane called ‘_documentHost’.
The DockingManager object has the property DocumentsSource property attached to a custom
collection of declared as a Window4 property.
This is the code behind file:
public partial class Window4 : Window {
public Window4() {
MyDocs =
new ObservableCollection<DocumentContent>();
this.DataContext =
this;
InitializeComponent();
}
public ObservableCollection<DocumentContent> MyDocs { get; set; }
private void dockingManager_Loaded(
object sender, RoutedEventArgs e) { }
void doc_Closed(
object sender, EventArgs e) { }
void doc_Closing(
object sender, System.ComponentModel.CancelEventArgs e) { }
private void Button_Click(
object sender, RoutedEventArgs e) {
for (
int i = 0; i < 5; i++)
{
DemoDocument doc = new DemoDocument();
doc.Title = "Document " + (i);
doc.InfoTip = "Info tipo for " + doc.Title;
doc.ContentTypeDescription = "Sample document";
doc.Closing += new EventHandler<System.ComponentModel.CancelEventArgs>(doc_Closing);
doc.Closed += new EventHandler(doc_Closed);
MyDocs.Add(doc);
}
}
private void dockingManager_RequestDocumentClose(object sender, RequestDocumentCloseEventArgs e)
{
MyDocs.Remove(e.DocumentToClose);
}
}
When you push the button, Button_Click() handler adds 5 documents to MyDocs collection (DemoDocument is just a DocumentContent derived object). DockingManager shows these documents under _documentHost pane. Now, try move these documents anchoring to borders or leaving them as floating window. If you click again the button 5 new documents are added always on the first document pane. The first document pane created is always referenced by the DockingManager.MainDocumentPane property.
Now change the above XAML setting the ItemsSource property of the _documentHost object to MyDocs:
<Window x:Class="AvalonDockTest.Window4"
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="Text Document Source" Height="600" Width="800" >
<DockPanel>
<ToolBar DockPanel.Dock="Top">
<Button Content="Add Documents" Click="Button_Click"/>
</ToolBar>
<ad:DockingManager x:Name="dockingManager" Loaded="dockingManager_Loaded" >
<ad:DocumentPane x:Name="_documentHost" ItemsSource="{Binding Path=MyDocs}"/>
</ad:DockingManager>
</DockPanel>
</Window>
Running the application, you can’t drag any document without experiencing an InvalidOperationException. The reason is that just when a drag opertion starts, AvalonDock tries to remove the selected document from the container pane and WPF complains because it is no allowed a direct access to the Items property while ItemsSource property is set.
Another useful event that is added in the latest build is DockingManager.RequestDocumentClose event. This event is fired by AvalonDock when an user wants to close a document and a collection is linked to the DocumentsSource property. Attaching this event, one has the option to directly remove document from its private collection (MyDocs). In the above code take a look at dockingManager_RequestDocumentClose handler.
Latest build can be downloaded via SVN from:
http://avalondock.codeplex.com/SourceControl/ListDownloadableCommits.aspx
Currently rated 4.0 by 1 people
- Currently 4/5 Stars.
- 1
- 2
- 3
- 4
- 5