自定义依赖属性没有得到绑定的输入
本文关键字:绑定 输入 依赖 属性 自定义 | 更新日期: 2023-09-27 18:10:30
我正在创建一个UserControl与DependencyProperty,但DependencyProperty没有得到调用者传递的值。
我在自己的调查中发现了以下内容
-
如果我使用内置的用户控件,如TextBlock,一切工作。这将问题缩小到我的UserControl的实现(而不是调用UserControl的代码)
-
我的属性改变回调,我注册甚至没有被调用(好吧…至少断点没有被击中)
-
如果只看到这个问题,当我使用绑定提供依赖属性,所以这不起作用:
<common:MyUserControl MyDP="{Binding MyValue}"/>
但是我没有问题,如果我摆脱绑定和硬编码的值,所以这工作:
<common:MyUserControl MyDP="hardCodedValue"/>
下面是我的UserControl的代码:
public partial class MyUserControl : UserControl
{
public string MyDP
{
get { return (string)GetValue(MyDPProperty); }
set { SetValue(MyDPProperty, value); }
}
public static readonly DependencyProperty MyDPProperty =
DependencyProperty.Register(
"MyDP",
typeof(string),
typeof(MyUserControl),
new FrameworkPropertyMetadata(
"this is the default value",
new PropertyChangedCallback(MyUserControl.MyDPPropertyChanged)));
public static void MyDPPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
((MyUserControl)obj).MyDP = (string)e.NewValue;
}
public MyUserControl()
{
InitializeComponent();
this.DataContext = this;
}
}
这里是xaml
<Grid>
<TextBlock Text="{Binding MyDP}"/>
</Grid>
因为我能够使用内置的用户控件,如TextBlock,我不认为错误在于我的主机代码,但这里是,只是为了让你有一个完整的画面:
<StackPanel>
<common:MyUserControl MyDP="{Binding MyValue}"/>
</StackPanel>
public class MainWindowViewModel
{
public string MyValue { get { return "this is the real value."; } }
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new MainWindowViewModel();
}
}
UserControl中的这一行是错误的:
this.DataContext = this;
这使得UserControl成为它自己的DataContext,所以绑定在UserControl上寻找一个名为MyValue的属性,而这个属性不存在。您希望DataContext作为您的视图模型。如果你不显式地设置它,它将从它的容器(在这个例子中是Window)继承DataContext。
删掉那一行,你会离得更近。你也不需要那个回调;
你可以这样更新你的控件的视图代码:
<Grid>
<TextBlock x:Name="_textBlock"/>
</Grid>
并在MyDPPropertyChanged方法中设置_textBlock的文本属性:
public static void MyDPPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
var control = ((MyUserControl)obj);
control.MyDP = (string)e.NewValue;
control._textBlock.Text = control.MyDP;
}
请在控件和视图模型中实现INotifyPropertyChanged和PropertyChangedEventHandler。其次,使用SetCurrentValue方法在控件类中设置值,而不是直接设置