views:

226

answers:

1

Hi all

I have a UserControl with a DependencyProperty. I set it's value in the host window using a data binding expression. However, it doesn't work as expected.

Snippet from the user control's codebehind:

public class ViewBase : UserControl
{
    public static readonly DependencyProperty ViewModelProperty
        = DependencyProperty.Register(
            "ViewModel", typeof(ViewModelBase), typeof(ViewBase));

    public ViewModelBase ViewModel
    {
        get { return GetValue(ViewModelProperty) as ViewModelBase; }
        set
        {
            SetValue(ViewModelProperty, value);
        }
    }
}

And from the XAML (note: CasingListView inherits from ViewBase):

<CasingEditor:CasingListView x:Name="_casingListView"
                             ViewModel="{Binding CasingListViewModel}" />

What happens is nothing. Specifically, the setter is never called, and the property remains null. I know the source property CasingListViewModel has a value, because I have tried to bind it to another property (DataContext), and it worked fine.

I thought a dependency property could be databound. Am I wrong?

+5  A: 

Hi again.

As sometimes happens, the problem turned out to be not quite what we thought.

I mentioned that the setter was never called. That is true. The code above is slightly trimmed to make it clearer. Unfortunately, I also trimmed away a statement in the setter, following the call to SetValue. That statement assigned the value to DataContext, something like this:

public ViewModelBase ViewModel
{
    get { return GetValue(ViewModelProperty) as ViewModelBase; }
    set
    {
        SetValue(ViewModelProperty, value);
        DataContext = value;
    }
}

As I have now learned from this excellent article, the setter is in fact bypassed when the property is set via databinding. The framework instead works directly against the DependencyObject. So the property was actually set, but the setter was never called (as I mentioned), and the consequence was that DataContext remained null and nothing worked.

So: First I apologize profusely for asking an unanswerable question. Second, as a way of making up for it, I can pass on the very important piece of advice:

Never put anything but GetValue() and SetValue() inside the property getter/setter, because they are not always called!

Edit: Later, I've also discovered another problem with this approach. By setting the DataContext this way, I actually lose the original data context that supports the binding in the first place. The result is that the property is immediately reset to null. So all in all not a good approach overall.

Tor Haugen
mark this as answered
Aran Mulholland
I will, but I'm not allowed to yet - there's a 2 day delay for accepting your own answer.
Tor Haugen