DataContext change doesn't change target

Oct 7, 2010 at 11:21 AM

When a control doesn't use Action.Target* but only DataContext, then the target isn't updated when the DataContext changes. Let's say I have a list of items and a button bound to list.SelectedItem:

        <Button DataContext="{Binding ElementName=list, Path=SelectedItem}"

Pressing the button will invoke Test() always on the first item you selected from the list.
If you select another one and SelectedItem changes the buttons DataContext, Test() will still
be invoked on the previous item, because context.Target doesn't get updated.

Oct 7, 2010 at 1:12 PM

This is by design. Action.Target exists to allow the target of actions to vary independently from DataContext, which is extremely important in some situations. So, changing the DataContext will not change the Action.Target. Setting Action.Target does set DataContext, but setting DataContext does not set Action.Target. Setting. Action.TargetWithoutContext sets only the Action.Target and not the DataContext. In your scenario, simply change the DataContext binding to be a binding on Action.Target.

Oct 7, 2010 at 2:05 PM

OK. Thx! Would probably be a good candidate for an FAQ entry.

Apr 6, 2011 at 2:58 PM
Edited Apr 6, 2011 at 2:58 PM

@EisenbergEffect, could you please take a look, whether this is still working?

I understood that etobi should change as follows:

        <Button Micro:Action.Target="{Binding ElementName=list, Path=SelectedItem}"

I'm trying nearly exactly the same, but binding always remains on the first bounded ViewModel.
Please see this thread:

Maybe there is a problem in ActionMessage.Invoke. After the first Item/ViewModel has been bound,
the context.Target remains at this Item. And I don't see any possibility for me that ActionMessage.UpdateContext
might be executed.

if(context.Target == null || context.View == null) {
    if (context.Target == null)
        var ex = new Exception(string.Format("No target found for method {0}.", context.Message.MethodName));

        if (!ThrowsExceptions)
        throw ex;
    if (!UpdateAvailabilityCore())

Im just using the latest sourcecode of Caliburn.Micro.
If it has been working on Oct 7 2010, then there might have been changes in the meantime?
Would be very grateful if you could check this.

Apr 6, 2011 at 3:38 PM

Please email me a sample ASAP. I'm prepping for a release on Monday and if you don't get it to me in a day or two at most, it won't get fixed in time. Please make the sample as simple as possible to demonstrate the problem. You can email me at robertheisenberg at hotmail dot com Before you send the sample, make the Action.Target binding mode two way and see if that fixes the problem.

Apr 6, 2011 at 4:07 PM

Thank. I will do tomorrow morning CET, just left the office and got no VS here.  Will crosscheck the Binding mode first and then prepare a simple sample. Hope the mistake is on my side :)

Apr 7, 2011 at 3:54 PM

There were two bugs. One in your code and one in mine. I've fixed the Caliburn.Micro bug. The sample you sent had the button's DataContext binding to the list box. You will need to change it to Action.Target like the above xaml.

Apr 8, 2011 at 7:15 AM

DataContext? Oh my god, that's embarrasing, you must think I'm dumb :)
Sorry, yesterday I played a while with the sample and obviously the last thing I tried was the DataContext again (after Action.Target)
Which is of course a useless undertaking, especially if you are posting in a thread, clearly stating that Datacontext only will not work.   Facepalm :)

But thank you very much indeed for your kind support here. Keep up the good work.

Apr 8, 2011 at 2:19 PM

It's an easy mistake to make :) Anyways, I'm thankful that you found this issue before release.