Binding convention error

Aug 26, 2010 at 12:32 PM

I've got a very strange binding convention error which is easy to reproduce. I've set up a bootstrapper using MEF, and then just created a ShellView, ShellViewModel combination. When the Test() method is triggered from the button click, I am getting an exception with the following message:

{"Could not locate any instances of contract Hello world."}

If I instead use a binding on the label like this "Content={Binding BusyMessage}", it works as expected.

Here's the code:

ShellView:

<Window x:Class="CaliburnBindingBug.ShellView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ShellView" Height="300" Width="300">
    <Grid>
        <StackPanel>
            <Label Name="BusyMessage"/>
            <Button Name="Test" Content="Test"/>
        </StackPanel>
    </Grid>
</Window>

ShellViewModel:

    [Export(typeof(IShell))]
    public class ShellViewModel : Conductor<IShell>.Collection.OneActive, IShell
    {
        private string busyMessage;

        public string BusyMessage
        {
            get { return busyMessage; }
            set
            {
                busyMessage = value;
                NotifyOfPropertyChange("BusyMessage");
            }
        }

        public void Test()
        {
            BusyMessage = "Hello world";
        }
    }

Coordinator
Aug 26, 2010 at 2:55 PM

I understand the problem and will create a ticket to fix it. Here is what is happening. It recognizes the convention binding between the label control and the BusyMessage property and creates the correct binding. However, it then notices that Label is actually a ContentControl and applies a default rule to change the binding from bound to the Content property to bound to the View.Model property. As a result, the text "Hello World" is pumped into the View.Model property. When this property sees a string, it thinks you are trying to resolve a VM from the IoC container by Key. So, it wants to get that from IoC, locate it's view, bind the two and stuff it into the Label's content. That's obviously not what you want here though :) It's easy for me to fix this, but I have seen this happen a couple times with different controls lately, so I may want to take a little time and see if I can come up with a better solution that what I have currently.

Aug 26, 2010 at 4:16 PM

Since there is a workaround, it is not an issue for me.

 

Thanks,

Magnus

Aug 27, 2010 at 5:14 AM

Isn't this a little problem in ConvetionManager.EnsureDependencyProperty? It shouldn't fallback to View.ModelProperty, if I really don't want a content binding for the given ElementConvention. (E.g. ToggleButton->CheckBox IsChecked)

Coordinator
Aug 27, 2010 at 12:55 PM

You are correct. I'm probably going to rework that piece a little bit. I'm thinking about the best solution. Any thoughts are appreciated.