Trying to bind a list of submodels to a ListView

Sep 6, 2010 at 4:04 PM

Hi Guys,

I'm currently trying to build a MDI window. The basic samples worked just fine so far, but I've been struggling a bit.

So here's the ShellViewModel:

public class ShellViewModel : PropertyChangedBase
    public ShellViewModel()
        AvailableScreens = new BindableCollection<MdiViewModel>();
        var mdiViewModel = new ProductListViewModel();
        CurrentActiveView = mdiViewModel;

    public IList<MdiViewModel> AvailableScreens { get; set; }

    private MdiViewModel currentActiveView;

    public MdiViewModel CurrentActiveView
        get { return currentActiveView; }
            currentActiveView = value;
            NotifyOfPropertyChange(() => CurrentActiveView);

The View is not that spectacular so far as I'm still playing around with this stuff:

<UserControl x:Class="Life.Store.Client.Views.ShellView"
             xmlns:vw="clr-namespace:Life.Store.Client.Views" mc:Ignorable="d" 
             d:DesignHeight="600" d:DesignWidth="800" Height="600" Width="800">
            <DataTemplate DataType="{x:Type ViewModels:ProductListViewModel}">
                <vw:ProductListView />
            <ColumnDefinition Width="150" />
        	<ColumnDefinition />
        <StackPanel Grid.Column="0">
            <Separator />
            <ListView x:Name="AvailableScreens">
                            <BulletDecorator />
                            <Button x:Name="DisplayView">
                                <TextBlock Text="{Binding Path=Name, UpdateSourceTrigger=PropertyChanged}" />
            <Separator />
            <Button x:Name="DisplayView" Content="Click me" />
        <ContentPresenter Grid.Column="1" Content="{Binding Path=CurrentActiveView}" DataContext="{Binding CurrentActiveView}" Width="200" Height="300">

So here are my issues:

In the DataTemplate I can't bind with the familiar x:Name syntax but have to write Binding expressions like this:

<TextBlock Text="{Binding Path=Name, UpdateSourceTrigger=PropertyChanged}" />
The ProductListViewModel I am trying to bind the ListViewItem also exposed the method: DisplayView() and it never gets called.
Since it's no ICommand I don't know how do bind to it through a Binding Expression, and since the x:Name="DisplayView" is not working I'm a bit lost :)

Hope this makes some sense.. Caliburn looks really cool and I really really like the MVVM approach it enables, but since I'm still new to WPF and Caliburn I find myself clueless all the time :)
I'm also a bit puzzled that there aren't that any good tutorials on how to build a Tabbed Application Shell with Caliburn.Micro since it seems to me like this is a fairly common szenario..

While at it: What's the correct way to open up a Modal Dialog Window with MVVM? Submodel hanging off the openening windows ViewModel? Is this possible with pure XAML and binding expressions or would I just write that inside a command?

Anyway, thanks for this great framework. 

greetings Daniel
Sep 6, 2010 at 4:33 PM

Unfortunately, we cannot automatically apply conventions to the contents of DataTemplates. The reason for this is that we have no way of intercepting WPF/Silverlight's template creation mechanism. To get around this you have a few options:

1. Do not use conventions inside of DataTemplates; Use explicit bindings and Message.Attach instead.

2. Extract all DataTemplates into UserControls which will re-enable conventions across the UserControl assuming you are using Convention binding to those controls or View.Model syntax. This is a good idea for large templates, but tedious for small ones

3. Use the Bind.Model attached property on the root UIElement of the DataTemplate like this Bind.Model="{Binding}" Doing this will cause conventions to be bound against the DataTemplate.


Also, you may want to consider using Conductor<T>.WithCollection.OneActive as your base class. This has the concept of a screen collection and a current screen. Databinding this class can allow you to easily set up an MDI-type shell. I have a blog post coming in the near future on Screens/Conductors in CM with a Billy-Hollis style sample shell which will demonstrate some of this.

The easiest way to show an application-wide modal dialog is to use the WindowManager. Pass it a view model and it will find the view, bind them and show it in a Window/ChildWindow. I'll be covering the WindowManager after the Screens/Conductors article :)

Sep 6, 2010 at 8:52 PM

Thanks for the help!

Are you going to write a book on Caliburn? That would be really great.. 

There are so many patterns and concepts involved in building a good MVVM WPF Application so a good book on that topic would be very interesting..


greetings Daniel

Sep 7, 2010 at 8:40 AM

Another Question just came to mind: What if I can't use convention based binding with Caliburn and want to bind a Button to a Command?

My ViewModels are freed from the ICommand hassle through Caliburn, but how do I bind the methods if the x:Name Syntax is not working?


greetings Daniel

Sep 7, 2010 at 1:53 PM

Hi Daniel,

Use Message.Attach as Rob suggested in his list of options. I ran into the same problem with my datatemplates and Message.Attach works perfectly.

Sep 7, 2010 at 2:25 PM

I highly recommend reading through the documentation. Many of these questions are answered in there :)