C# WPF依赖属性回调
我有一个具有依赖属性的用户控件,我正在wpf窗口中使用此控件。当我从窗口视图模型更改作为该依赖项属性绑定的属性的值时,我希望调用该依赖项属性的回调方法,但什么也没有发生 MainWindow.xamlC# WPF依赖属性回调,c#,wpf,dependency-properties,C#,Wpf,Dependency Properties,我有一个具有依赖属性的用户控件,我正在wpf窗口中使用此控件。当我从窗口视图模型更改作为该依赖项属性绑定的属性的值时,我希望调用该依赖项属性的回调方法,但什么也没有发生 MainWindow.xaml <test:TestView Grid.Column="0" TestString="{Binding TestString, Mode=TwoWay}"></test:TestView> MainWindowViewModel.cs private string _
<test:TestView Grid.Column="0" TestString="{Binding TestString, Mode=TwoWay}"></test:TestView>
MainWindowViewModel.cs
private string _testString;
public string TestString
{
get { return _testString; }
set
{
if (_testString!= value)
{
_testString= value;
OnPropertyChanged();
}
}
}
TestView.xaml.cs
public TestView()
{
InitializeComponent();
this.DataContext = new TestViewModel();
}
public static readonly DependencyProperty TestStringProperty =
DependencyProperty.Register("TestString", typeof(string), typeof(TestView), new PropertyMetadata(null, OnTestStringPropertyChanged));
public string TestString
{
get { return (string)GetValue(TestStringProperty); }
set
{
SetValue(TestStringProperty, value);
}
}
private static void OnTestStringPropertyChanged(DependencyObject source,
DependencyPropertyChangedEventArgs e)
{
TestView control = source as TestView;
string time = (string)e.NewValue;
// Put some update logic here...
((TestViewModel) control.DataContext).Merge();
}
BaseViewModel.cs(我在每个ViewModel中扩展它)
我在这里做错了什么,或者为什么我的回调从未被调用?我们可以看看您是如何实现的
INotifyPropertyChanged
?删除this.DataContext=new TestViewModel()来自UserControl的构造函数的代码>。它会中断任何基于DataContext的绑定,如TestString=“{Binding TestString,Mode=TwoWay}”
。UserControl永远不应该显式设置自己的DataContext。@scharette我编辑了这个问题,现在您也可以看到实现,如果INotifyPropertyChangedAs说,UserControl永远不应该显式设置自己的DataContext。既不是对自身,也不是对某些“私有”视图模型。它应该只公开绑定到外部提供的视图模型属性的依赖属性,即UserControl父元素的DataContext属性的值继承提供的依赖属性,例如MainWindow。这正是您应该做的。
public TestView()
{
InitializeComponent();
this.DataContext = new TestViewModel();
}
public static readonly DependencyProperty TestStringProperty =
DependencyProperty.Register("TestString", typeof(string), typeof(TestView), new PropertyMetadata(null, OnTestStringPropertyChanged));
public string TestString
{
get { return (string)GetValue(TestStringProperty); }
set
{
SetValue(TestStringProperty, value);
}
}
private static void OnTestStringPropertyChanged(DependencyObject source,
DependencyPropertyChangedEventArgs e)
{
TestView control = source as TestView;
string time = (string)e.NewValue;
// Put some update logic here...
((TestViewModel) control.DataContext).Merge();
}
public class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}