从UserControl的DependencyProperty绑定不起作用

时间:2014-02-26 12:37:28

标签: c# wpf mvvm binding dependency-properties

我有一个UserControl,其中一个DependencyProperty在代码隐藏中设置 (我想这可能是我的问题的根源,但仍然不知道该怎么做):

用户控件

 public partial class MyControl
{
    public MyControl()
    {
        InitializeComponent();
    }

    public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(MyControl),
       new FrameworkPropertyMetadata("",FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); InvokePropertyChanged(new PropertyChangedEventArgs("Text"));}
    }

    public static string GetText(DependencyObject obj)
    {
        return (string)obj.GetValue(TextProperty);
    }

    public static void SetText(DependencyObject obj, string value)
    {
        obj.SetValue(TextProperty, value);
    }

    private void ChangeText()
    {
        Text="some value";
    }
}

在我的View.xaml中,我使用这个控件:

 <MyControl Text="{Binding Text, RelativeSource={RelativeSource Self}, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>

我的ViewModel中的Text属性:

 private string _text;
    public string Text
    {
        get { return _text; }
        set { _text= value; InvokePropertyChanged(new PropertyChangedEventArgs("Text"));}
    }

问题: ViewModel中的Text属性永远不会更新;当使用像TextBox这样的常规控件绑定时,一切都很完美;如果我在XAML中设置Text,则UserControl的Text propery会更新。 我做错了什么?


更新 我的问题是我在MyControl上明确设置了DataContext。

2 个答案:

答案 0 :(得分:3)

问题在你的装订中:

Text="{Binding Text, RelativeSource={RelativeSource Self}, 
               UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"

Text属性位于您的ViewModel中,但您通过使用RealtiveSource指向自己来引用自身。因此,它将Text DP与自身绑定。

如果您设置了控件的DataContext,它将自动从父级继承DataContext。因此,您根本不需要RelativeSource

它应该是:

Text="{Binding Text}"

几点(但与您的问题无关)

  • 由于您的目标是在控件内使用此属性,因此请使用普通DP而不是附加属性。

  • 从注册时起,您已将其设置为默认绑定TwoWay。在绑定时无需明确地这样做。

  • 从DP包装器设置器中删除InvokePropertyChanged调用。不会从XAML调用Setter,并且DP已经知道了PropertyChanged。


<强>更新

如果DataContext的{​​{1}}设置为另一个类的实例,则上述方法将在MyControl DataContext中搜索MyControl属性。

您可以传递父控件的DataContext(在您的情况下为StackPanel),如下所示:

Text

答案 1 :(得分:1)

您已将您的财产注册为附件,但您也将其用作常规DependencyProperty。我认为xaml解析器会混淆。决定你要使用哪一个。