Using DocumentPane.ItemTemplate with custom Collection as ItemsSource

Mar 2, 2009 at 1:31 PM
Edited Mar 2, 2009 at 1:32 PM
Hello,

I am currently building an application using MVVM and my main window uses AvalonDock for the workspaces.
Now i want to set my DocumentPane's ItemsSource to an ObservableCollection<WorkspaceViewModel> on my main window view model, using a DataTemplate to put the viewmodels into actual tabs, and using a typed datatemplate to display the content based on the viewmodel.
Now when i try to add a WorkspaceViewModel to the ItemsSource, i get an exception saying "DocumentPane can contain only DockableContents or DocumentContents" in OnItemsChanged in DocumentPane.cs, since the new list item is a WorkspaceViewModel, not a documentcontent. I commented it out temporarily, but in other places ManagedContent is expected, and then my new item is a contentpresenter, which doesn't work well either.
I thought it's enough to set the DataTemplate's root element to a DocumentContent, but i'm probably just doing something plain wrong.

Can anyone help me?

My DocumentPane looks like this:

    <ad:DocumentPane x:Name="documentsHost"
              ItemsSource="{Binding Workspaces}"
              ItemTemplate="{StaticResource WorkspaceTemplate}">
    </ad:DocumentPane>

The DataTemplate looks like this:

   <DataTemplate x:Key="WorkspaceTemplate">
          <ad:DocumentContent Title="{Binding DisplayName}">
                 <ContentPresenter Content="{Binding}"/>
         </ad:DocumentContent>

   </DataTemplate>
Mar 2, 2009 at 1:42 PM
Hi,

I had quite the same problem and the alternative I found, was to create a child class from DocumentContent in which I set the Content attribute to a UserControl I created to display my custom objects.
It looks like that :


I don't know if it is a clean solution but it worked for me.
    /// <summary>
    /// Class that can be stored in a DocumentPane (from AvalonDock API) and which content is my user control.
    /// </summary>
    public class MyDocumentContent : DocumentContent
    {   
        private MyUserControl myUserControl_m;

        public MyDocumentContent (MyUserControl  myUserControl_p)
        {
            myUserControl_m = myUserControl_p;

            Title = myUserControl_m.Label;
            Content = myUserControl_m;
        }

        public MyUserControl  CustomObject 
        {
            get { return myUserControl_m; }
            set
            {
                myUserControl_m = value;
                // Reload content
                Content = myUserControl_m;
                Title = myUserControl_m.Label;
            }
        }
    }

where MyUserControl  is a UserControl that I created to display my data.

I don't know if it is a clean solution but it worked for me.
Hope it helps...
Mar 2, 2009 at 6:05 PM
Thanks. I did that now in my application, the DocumentPane's ItemsSource is set to a list of the derived DocumentContent class owned by the ViewModel, and now they do at least show up :)

Only problem is, when i want to drag a tab around, the documentpane temporarily removes it from it's items list and that creates an error saying that the collection can not be modified, and that i should directly modify the source collection instead.
I guess i'm still doing something wrong, or maybe i should take a look at another approach.