我有一个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。
答案 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解析器会混淆。决定你要使用哪一个。