Twoway在自定义控件和viewModel的依赖属性之间进行数据绑定

时间:2016-07-27 18:11:49

标签: c# wpf mvvm data-binding

我有自定义控件

class SearchComboBox : ComboBox,  INotifyPropertyChanged
{
    public static readonly DependencyProperty ChoosenItemProperty = DependencyProperty.Register(
    "ChoosenItem",
    typeof(ISearchable),
    typeof(SearchComboBox))

    public ISearchable ChoosenItem
    {
        get
        {
            return (ISearchable)GetValue(ChoosenItemProperty);
        }

        set
        {
            SetValue(SearcherProperty, value);
        }
    }

      private void SearchComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
      {          
          var selected = this.SelectedItem as ISearchable;
          ChoosenItem = selected;
      }
}

在XAML中,我将自定义属性绑定到ViewModel:

<controls:SearchComboBox ChoosenItem="{Binding SearchableAuthor, Mode=TwoWay}" Width="219"/>

要绑定的VM属性:

public ISearchable SearchableAuthor
    {
        get
        {
            return searchAuthor;
        }
        set
        {
            searchAuthor = value;
            OnPropertyChanged("SearchableAuthor");
        }
    }

当我在VM的用户控件ChoosenItem中修改SearchableAuthor时也会发生变化,但当我尝试更改SearchableAuthor时,ChoosenItem保持不变。 如何从ViewModel更新此属性?

2 个答案:

答案 0 :(得分:0)

添加RelativeSource或ElementName以使其正常工作。

<controls:SearchComboBox ChoosenItem="{Binding SearchableAuthor, 
   RelativeSource={RelativeSource AncestorType={x:Type Window}}, 
   Mode=TwoWay}" Width="219"/>

<controls:SearchComboBox ChoosenItem="{Binding SearchableAuthor, 
   RelativeSource={RelativeSource AncestorType={x:Type Window}}, 
   Mode=TwoWay}" Width="219"/>

您可能还需要将控件的DataContext设置为自身

public control()
{
    InitializeComponent();
    this.DataContext = this;
}

答案 1 :(得分:0)

我已经得到了解决方案 - 将ValueChanged监听器添加到依赖属性:

 public TestBindingButton() : base()
    {
        this.Click += TestBindingButton_Click;
        var prop = DependencyPropertyDescriptor.FromProperty(ChoosenItemProperty, typeof(TestBindingButton));
        prop.AddValueChanged(this, SourceChangedHandler);

    }

并手动访问getter:

void SourceChangedHandler(object sender, EventArgs e)
    {
        this.Content = ChoosenItem;
    }

示范项目,以展示我尝试实现的目标:TwoWayBinding