12
votes

I'm trying to create something like a MDI tabbed Interface so I have a navigation pane (a Listbox) on the left, and a ContentPresenter on the right.

I have a ShellViewModel that has a BindableCollection on it called AvailAbleScreens and I managed successfully to bind to that list with a ListViews DataTemplate:

<ListView x:Name="AvailableScreens">
    <ListView.ItemTemplate>
        <DataTemplate>
            <WrapPanel>
                <BulletDecorator />
                <Button x:Name="DisplayView">
                    <TextBlock Text="{Binding Path=Name, UpdateSourceTrigger=PropertyChanged}" />
                </Button>
            </WrapPanel>
        </DataTemplate>
    </ListView.ItemTemplate>

The problem now is that although the Name of the Button is set correctly, I can't make the Command fire for me. On the MdiViewModel class I have the following code for that button:

public bool CanDisplayView()
{
    return true;
}

public void DisplayView()
{
    MessageBox.Show("Hello");
}

All the Caliburn.Micro samples work with binding through conventions to the x:Name Property, but if I remove the Text="{Binding}" it stops working so I suspect that this way of databinding doesn't work for sub-models?

Anyway, the Shell's ViewModel is quite simple at the moment:

ShellViewModel
 * AvailableScreens
    -MdiViewModel1
    -MdiViewModel2
 * CurrentActiveScreen

Any Idea how I'd do this with Caliburn.Micro? Rob Eisenberg suggested to me on Twitter I might want to start out with Caliburn.Micro before going into the full fledged Caliburn framework.

1

1 Answers

20
votes

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 couple of 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-enalbe conventions across the UserControl. 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. Unfortunately, this may not quite work right due to some bugs in Caliburn. It does work in Caliburn.Micro though. I'm hoping to work that bug out soon.