Sinatr
Sinatr

Reputation: 21989

Two way binding ignores source changes

I have custom control with dependency property and binding to ViewModel property only works like OneWayToSource. What did I mess up?

Binding

<local:MyControl SelectedItem="{Binding SelectedPage}"/>

ViewModel and control

public class ViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private ViewModelPageBase _selectedPage;
    public ViewModelPageBase SelectedPage
    {
        get { return _selectedPage; }
        set
        {
            _selectedPage = value;
            OnPropertyChanged();
        }
    }

    public void OnPropertyChanged([CallerMemberName] string property = "")
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(property));
    }
}

public class MyControl : ContentControl
{
    public object SelectedItem
    {
        get { return (object)GetValue(SelectedItemProperty); }
        set
        {
            // never get here
            SetValue(SelectedItemProperty, value);
        }
    }
    public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register(
        "SelectedItem",
        typeof(object),
        typeof(MyControl),
        new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
}

Earlier I was using ItemsControl and binding was working two-way. Now, with MyControl, only if SelectedItem is changed, then SelectedPage get updated. Other way (setting SelectedPage somewhere) doesn't update SelectedItem.

Ideas?

Upvotes: 1

Views: 164

Answers (3)

William guth
William guth

Reputation: 46

I see two problem:

Firstly you forgot the closed }:

SelectedItem="{Binding SelectedPage}"

Secondly on your Dependency Property, the third object should be your owner class. In your case MyControl

public static readonly DependencyProperty SelectedItemProperty =
DependencyProperty.Register(
     "SelectedItem",
     typeof(object),
     typeof(**ViewNavigatorControl**),
     new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

But maybe this mistake are only a bad copy/paste.

Upvotes: 1

William guth
William guth

Reputation: 46

i see your comment on the setter of the dependency property :

public object SelectedItem { get { return (object)GetValue(SelectedItemProperty); } set { // never get here SetValue(SelectedItemProperty, value); } }

I think you already know that, but in case you don't in Dependency Property the setter is never call, if you want to be notify of any change, you should add a PropertyChangedCallback in the third parameter of FrameworkPropertyMetadata

Setters not run on Dependency Properties?

Upvotes: 2

Sivasubramanian
Sivasubramanian

Reputation: 955

In the selectedItem Dependancyproperty declaration,

public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register(
        "SelectedItem",
        typeof(object),
        typeof(ViewNavigatorControl),
        new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));



typeof(ViewNavigatorControl) should be replaced by typeof(MyControl)

Let me know whether this resolves the issue

Upvotes: 2

Related Questions