This project is read-only.

Why doesn't data binding work with DocumentPane ?

Feb 17, 2010 at 5:03 AM
Edited Feb 17, 2010 at 5:04 AM

DocumentPane is a Selector ( a derivation of WPF's ItemsControl type)

So I attempted to bind it against a list of DocumentViewModel instances -

<ad:DocumentPane ItemsSource="{Binding Documents}" />


I want one DocumentContent per instance inside the DocumentPane; this DataTemplate serves that purpose

<DataTemplate DataType="{x:Type local:DocumentVM}">
                <ad:DocumentContent Title="Databound Yeti">
                    <StackPanel>
                        <TextBlock>This is a document</TextBlock>
                    </StackPanel>
                </ad:DocumentContent>
            </DataTemplate>
        </ResourceDictionary>
                      

I've tried a bunch of stuff but I keep getting an error message that I can't comprehend

Unable to cast object of type 'System.Windows.Controls.ContentPresenter' to type 'AvalonDock.ManagedContent'.

It seems that I can add DocumentContent instances to DocumentPane via XAML but not via Data-Binding.

                      <ad:DocumentPane x:Name="Home">
                        <ad:DocumentContent Title=" is back">
                            <Canvas/>
                        </ad:DocumentContent>
                        <ad:DocumentContent Title=" got his friends too!!">
                            <Canvas/>
                        </ad:DocumentContent>
                    </ad:DocumentPane>

Is this broken or does AvalonDock have a different mechanism to achieve this ?

Feb 17, 2010 at 4:30 PM
Edited Feb 17, 2010 at 4:31 PM

Turns out that AvalonDock does not handle DataTemplates well.

What you can do is the following:

<AvalonDock:DockingManager DocumentsSource="{Binding Path=ViewManager.Views}" Name ="_DockingManager" RequestDocumentClose="_DockingManager_RequestDocumentClose" >
            <AvalonDock:DocumentPane x:Name="_documentHost" />                           
</AvalonDock:DockingManager>
in this case ViewManager.Views is of type 
ObservableCollection<IDockableView> Views { get; set; }
and IDockableView is a marker interface for DocumentContent which I need to seperate this binding mess 
from the rest of my code.
This is as good as MVVM gets with AvalonDock as far as I know.
-Thorsten
Feb 18, 2010 at 11:00 AM

Thanks Thorsten.

I ended up with a workaround as well.. I needed a DocumentPane to contain a bunch of documents (bound to a collection). It's more code in the code-behind (view) that I'd like but guess I need to cut this corner.

Have the ShellVM (the main VM) maintain an observable collection of DocumentVMs.

In the OnCollectionChanged event handler in the view, for each new item,

                    var docVM = newDocument as DocumentVM;        // view model for the document
                    var container = new DocumentContent();

                    container.Title = docVM.Name;
                    container.SetBinding(ContentPresenter.ContentProperty, new Binding(String.Empty));

                    container.DataContext = docVM;                    
                    container.Closing += delegate(object senderObj, CancelEventArgs evtArgs)
                    {
                        _shellVM.CloseAppDataTable(docVM.Name);      // view model for the main window 
                        evtArgs.Cancel = true;
                    };
                    _adDocPane.Items.Add(container);

I have a Typed DataTemplate for DocumentVM in the XAML for the window.

            <DataTemplate DataType="{x:Type local:DocumentVM}">
                <DockPanel>
                    <toolkit:DataGrid ItemsSource="{Binding Path=MyDataTable}" />
                </DockPanel>
            </DataTemplate>

Nov 9, 2010 at 3:34 AM

Does the developer realize how important item templates are? If not, are there any people considering fixing the problem?

Jun 28, 2013 at 2:57 PM
Hi,

Can you please provide small sample project of how you achieved your work around. I am struggling to get my project running with documents.

Thank you
Carl Fischer