Binding the ViewModel itself inside a DataTemplate

Topics: Conventions, Getting Started
Jun 22, 2012 at 5:16 PM

I'm a newcomer to Caliburn.Micro and there are a few things I'm still not getting.

ViewModel first:

First of is a ViewModel that manages a Collection of other ViewModels:

public class NavigationBarViewModel : PropertyChangedBase
    {
        public BindableCollection<IHaveDisplayName> Items { get; set; }
    }

I've got a ItemsControl (it's Telerik RadOutlookBar if that matters) as the root of a UserControl

of that view and I set the ItemTemplate too ensure that the ViewModels I insert into the collection are wrapped in a corresponding RadOutlookBarItem (  should I use ItemContainer instead of ItemTemplate here? ).

<telerik:RadOutlookBar x:Name="Items">
        <telerik:RadOutlookBar.TitleTemplate>
            <DataTemplate>
                <ContentControl Content="{Binding Path=DisplayName}" />
            </DataTemplate>
        </telerik:RadOutlookBar.TitleTemplate>
        <telerik:RadOutlookBar.ItemTemplate>
            <DataTemplate>
                <telerik:RadOutlookBarItem cal:Bind.Model="{Binding}"
                                           Header="{Binding Path=DisplayName}">
                    <ContentControl />
                </telerik:RadOutlookBarItem>
            </DataTemplate>
        </telerik:RadOutlookBar.ItemTemplate>
    </telerik:RadOutlookBar>

This way I wan't the ViewModels in the collection to appear where the ContentControl is. I Bind the model to the root item of the DataTemplate to ensure conventions will work but have no idea how to bind to the ContentControl with convention. The DataContext inside the DataTemplate is of course the ViewModel itself. Using normal WPF standard I would put Content="{Binding}".

Now the model is there inside the RadOutlookBarItem but it's view doesn't get applied. Not even View can't be found, only a string with the class name.

Isn't this the proper way to do this?

 

Jun 22, 2012 at 6:05 PM

The ItemTemplate on this particular control describes what's in the MenuItem thingy instead of the proper ContentWindow. So when I left ItemTemplate empty the Convention of Caliburn took over and injected the view there (essentially the wrong place). So I needed to inject it into the ContentTemplate (Telerik naming seems to fudge things up here) and used the standard naming convention.

 

    <telerik:RadOutlookBar x:Name="Items">
        <telerik:RadOutlookBar.ContentTemplate>
            <DataTemplate >
                <ContentControl cal:View.Model="{Binding}" />
            </DataTemplate>
        </telerik:RadOutlookBar.ContentTemplate>
        <telerik:RadOutlookBar.TitleTemplate>
            <DataTemplate>
                <TextBlock x:Name="DisplayName"
                           cal:Bind.Model="{Binding}" />
            </DataTemplate>
        </telerik:RadOutlookBar.TitleTemplate>
        <telerik:RadOutlookBar.ItemTemplate>
            <DataTemplate>
                <TextBlock x:Name="DisplayName"
                           cal:Bind.Model="{Binding}" />
            </DataTemplate>
        </telerik:RadOutlookBar.ItemTemplate>
    </telerik:RadOutlookBar>