这里至少有两个问题。
首先,您依赖于正在执行的setxxx方法。当从xaml设置dp时,不会执行依赖项属性(property setter或setxxx方法)的clr包装器;相反,wpf直接设置内部托管dp“slot”的值。(这也解释了为什么从未命中断点。)因此,处理更改的逻辑必须始终发生在onxxxchanged回调中,
不
在setter中,当属性更改时,无论更改来自何处,WPF都将为您调用该回调。因此(示例来自命令的稍微不同的实现,但应该给您一个想法):
// Note callback in PropertyMetadata
public static readonly DependencyProperty CommandProperty =
DependencyProperty.RegisterAttached("Command", typeof(ICommand), typeof(Click),
new PropertyMetadata(OnCommandChanged));
// GetXxx and SetXxx wrappers contain boilerplate only
public static ICommand GetCommand(DependencyObject obj)
{
return (ICommand)obj.GetValue(CommandProperty);
}
public static void SetCommand(DependencyObject obj, ICommand value)
{
obj.SetValue(CommandProperty, value);
}
// WPF will call the following when the property is set, even when it's set in XAML
private static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ButtonBase button = d as ButtonBase;
if (button != null)
{
// do something with button.Click here
}
}
其次,即使进行了此更改,在尚未设置值的控件上设置clickcommand也会导致异常,因为oldvalue为空,因此oldvalue.action会导致nullreferenceexception。您需要检查这种情况(您还应该检查newValue==null,尽管这不太可能发生)。