在xaml中设置时,WPF附加属性不会触发代码

She*_*dan 4 wpf dependencies attached-properties

我有一个自定义ClockFace UserControl,它具有允许更改颜色,字体和手(作为Path对象)的属性.这用于自定义TimePicker和Clock UserControls.在这些父控件中,可以在xaml中的ClockFace对象上设置ClockFace属性.我正在尝试做的是暴露这些ClockFace属性,以便可以在这两个父控件(例如,Clock和TimePicker对象)上设置它们.我认为将它们作为附加属性可以解决问题,所以我尝试使用其中一种颜色属性.

public static readonly DependencyProperty HourTicksBrushProperty = DependencyProperty.RegisterAttached("HourTicksBrush", typeof(Brush), typeof(ClockFace), new FrameworkPropertyMetadata(Brushes.Black, FrameworkPropertyMetadataOptions.AffectsRender));
public static void SetHourTicksBrush(DependencyObject element, Brush value)
{
    element.SetValue(HourTicksBrushProperty, value);
}
public static Brush GetHourTicksBrush(DependencyObject element)
{
    return (Brush)element.GetValue(HourTicksBrushProperty);
}
Run Code Online (Sandbox Code Playgroud)

我可以在时钟所在的xaml中使用这个附加属性:(控件是xml命名空间)

<Controls:Clock Controls:ClockFace.HourTicksBrush="Aqua" />
Run Code Online (Sandbox Code Playgroud)

它编译得很好,但是虽然来自附加的HourTicksBrushProperty的默认值(Brushes.Black)显示,但在父时钟控件(Aqua)上设置的值永远不会触发上述方法或更改颜色.我错过了什么吗?

为了清楚起见,我希望能够在父控件上使用上面的xaml来设置子ClockFace控件的HourTicksBrush属性.

任何帮助将非常感激.

Rob*_*sor 6

附加属性类中的"get"和"set"方法实际上只是您自己的代码隐藏的便捷方法.XAML解析器忽略这些,调用element.SetValue本身.如果你想响应一个setter,你必须提供一个属性更改处理程序FrameworkPropertyMetadata

public static readonly DependencyProperty HourTicksBrushProperty = DependencyProperty.RegisterAttached(
    "HourTicksBrush", 
    typeof(Brush), 
    typeof(ClockFace), 
    new FrameworkPropertyMetadata(
        Brushes.Black, 
        FrameworkPropertyMetadataOptions.AffectsRender,
        HourTicksBrushChanged));

public static void SetHourTicksBrush(DependencyObject element, Brush value)
{
    element.SetValue(HourTicksBrushProperty, value); //not always called
}
public static Brush GetHourTicksBrush(DependencyObject element)
{
    return (Brush)element.GetValue(HourTicksBrushProperty); //not always called
}
private static void HourTicksBrushChanged(DependencyObject sender, somethingsomethingArgs args){
    // do stuff with sender and args.NewValue here
}
Run Code Online (Sandbox Code Playgroud)