Convention binding for templated objects?

Jan 26, 2011 at 2:58 PM

I can't seem to get convention-based binding to recognize methods/objects in a DataTemplate in WPF. I have a view model class that has a BindableCollection property. I'm dealing with IP cameras here, so the collection property is called Cameras. Each camera has public methods TurnOnLight and TurnOffLight. Using a data template, I'm showing several cameras and some buttons. The XAML is below:

        <StackPanel Orientation="Vertical" Margin="5">
            <Image Source="{Binding SnapshotImage}" Stretch="Fill" />
            <TextBlock Text="{Binding Name}" />
            <Button x:Name="TurnOnLight" Content="Turn On Light" />
            <Button x:Name="TurnOffLight" Content="Turn Off Light" />

I thought that the buttons would automatically be wired to their respective camera's methods, but this doesn't seem to be the case. The buttons appear, but the code isn't called when clicked. I'm very new to Caliburn (and WPF in general) so maybe I'm missing something.

Thanks for any suggestions.

Jan 26, 2011 at 3:52 PM

Unfortunately the WPF/SL/WP7 implementation of DataTemplate does not provide an extensibility point into which we can plug our convention behaviors. It is a limitation of the underlying platform. You can put an attribute on the root element of your template to "hook" CM manually. It would look like this:

<StackPanel Orientation="Vertical" Margin="5" cal:Bind.Model="{Binding}">

The Bind.Model attached property just binds the view model specified to the view on which the attribute exists, applying all conventions.

Jan 27, 2011 at 3:00 AM

Thanks, that worked just fine.

May 15, 2011 at 9:11 AM

Can i suggest added a section under conventions specifically for DataTemplates explaining this and the solution. It took me a while to discover that conventions were not applying to my data template and why.

May 15, 2011 at 4:21 PM

I made a note to add that to the docs.

Jul 27, 2011 at 5:08 PM

The docs look to be updated, but are wrong, they say to use cal:View.Model, not cal:Bind.Model.

Jul 27, 2011 at 10:03 PM

Oops. It's fixed now.

Mar 13, 2012 at 10:33 PM
Edited Mar 13, 2012 at 10:35 PM

Would this work if I have a Grid as a keyed resource?  I tried to add cal:View.Model="{Binding}" to it and it ended up ending an infinite loop in CM's INPC.cs.  Wonder if I'm doing something wrong here.


cal:Bind.Model="{Binding}" instead sets my View (passed in through OnViewLoaded(object view)) to the keyed resource that I set it on.  And, well, that doesn't seem right at all!