Setting up a DocumentItemTemplateSelector

Docking/MDI for WPF Forum

Posted 8 years ago by Tony Pulokas
Version: 11.1.0543
Avatar
Hello, I'm having trouble hooking up a DocumentItemTemplateSelector.

After ViewModels are added to the DocumentItemSource (type: ObservableCollection<ViewModelBase>) the template selector's SelectTemplate method is called; however, the problem is that the item parameter passed in is always null.

In the user control containing the docksite I set the data context, set up the static resources (templates and template selector), and then place the docksite:

    <UserControl.DataContext>
        <viewModels:MyViewModel />
    </UserControl.DataContext>

    <UserControl.Resources>
        <DataTemplate x:Key="myTemplateA">
            <views:MyViewA/>
        </DataTemplate>
        <DataTemplate x:Key="myTemplateB">
            <views:MyViewB/>
        </DataTemplate>
        
        <templateSelectors:DocumentTemplateSelector
                MyTemplateA="{StaticResource myTemplateA}"
                MyTemplateB="{StaticResource myTemplateB}"
                x:Key="documentTemplateSelector"/>
    </UserControl.Resources>

    <docking:DockSite x:Name="dockSite" 
                      viewModels:DockSiteViewModelBehavior.IsManaged="true"
                      DocumentItemsSource="{Binding DocumentViewModelList}"
                      DocumentItemTemplateSelector="{StaticResource documentTemplateSelector}">
        <docking:Workspace>
            <docking:TabbedMdiHost/>
        </docking:Workspace>
    </docking:DockSite>
Here is my basic template selector implementation:

    public class DocumentTemplateSelector : DataTemplateSelector
    {
        public DataTemplate MyTemplateA { get; set; }
        public DataTemplate MyTemplateB { get; set; }

        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            ...
        }
    }
I'm using a template selector elsewhere in my program (not within a Docksite) and it is set up the same as this one, except for the line that sets DockSiteViewModelBehavior.IsManaged. I added that to better emulate the MVVM-Docking-Windows example from the sample browser. Without it the docksite stays empty. With it the docksite loads and displays the string type of the viewmodel in a separate tab for each viewmodel in the list.


Any ideas on why the template selector would be receiving null items instead of the viewmodels that are added to the items source?

Do the viewmodels that I add to the items source need to implement anything special?

Or, is there any example usage of the DocumentItemTemplateSelector? I searched the sample browser but didn't find any examples there.

Thanks!

[Modified at 07/25/2011 03:24 PM]

Comments (3)

Posted 8 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi Tony,

By default, the item will only be assigned to the Content property of the docking windows. This differs from other headered items controls, which would also assign the item to the Header property if the item is not a visual. This is done because by default the Header is bound to the Title property.

You can pass the item to the Header property using an implicit Style like so:
<Style x:Key="{x:Type docking:DocumentWindow}" TargetType="{x:Type docking:DocumentWindow}">
    <Setter Property="Header" Value="{Binding}" />
</Style>

<Style x:Key="{x:Type docking:ToolWindow}" TargetType="{x:Type docking:ToolWindow}">
    <Setter Property="Header" Value="{Binding}" />
</Style>
Also, like other ItemsControls that use HeaderContentControls as their containers, the DocumentItemTemplate/Selector and ToolItemTemplate/Selector are only applied to the Header (via the HeaderTemplate/Selector properties). To apply a custom DataTemplate/Selector to the Content, you'd need to explicitly set the ContentTemplate/Selector on the DockingWindow.

Also, like other items controls that use a HeaderContentControl as their containers, the DocumentItemTemplate, DocumentItemTemplateSelector, ToolItemTemplate, and ToolItemTemplateSelector properties are only applied to the Header (via the HeaderTemplate and HeaderTemplateSelector properties). To apply a custom DataTemplate/DataTemplateSelector to the Content property, you'd need to explicitly set the ContentTemplate or ContentTemplateSelector on the docking window. This can be done using a style or in an override for the PrepareContainerForItemOverride method.

So I suspect you are not setting the Title, so Header would always be null (the default value for Title). You can either set the Title to a valid value, or use the Style above to pass the item to the Header property.

I've updated the documentation to include this information also.


Actipro Software Support

Posted 5 years ago by Scott Currie
Avatar

I've been having a lot of trouble getting this to work.  When I set the ContentTemplateSelector property in my DockingWindow style, then the Item in the ContentTemplateSelector and the DataContext for the DataTemplate becomes the ContentControl containing the ViewModel, rather than the ViewModel itself.

<Style
  TargetType="{x:Type apdock:DockingWindow}"
  >
  <Setter
    Property="ContentTemplateSelector"
    Value="{StaticResource EditorTemplateSelector}"
    />
</Style>

This results in the following SelectTemplate method where the actual ViewModel is in the Content property of item (which is a ContentControl):

public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
    var contentControl = item as ContentControl;
    if (contentControl != null && contentControl.Content != null)
    {
        return Application.Current.TryFindResource("editor_" + contentControl.Content.GetType().Name) as DataTemplate;                
    }
}

 Any ideas how I can go about fixing that without hacking DataContexts?

[Modified 5 years ago]

Posted 5 years ago by Scott Currie
Avatar

Actually, it looks like this is working now.  I'm not sure what the key to the fix was.  I didn't check in the broken version, so I can't run a diff to find out.  Thanks.

The latest build of this product (v2019.1 build 0683) was released 1 month ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.