【问题标题】:WPF attached properties not firing code behind when set in xaml在 xaml 中设置时,WPF 附加属性不会触发代码
【发布时间】:2010-10-17 17:36:32
【问题描述】:

我有一个自定义的 ClockFace UserControl,它具有允许更改颜色、字体和手(作为 Path 对象)的属性。这用于自定义 TimePicker 和时钟用户控件。在这些父控件中,可以在 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);
}

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

<Controls:Clock Controls:ClockFace.HourTicksBrush="Aqua" />

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

明确地说,我希望能够在父控件上使用上述 xaml 来设置子 ClockFace 控件的 HourTicksBrush 属性。

任何帮助将不胜感激。

【问题讨论】:

    标签: wpf dependencies attached-properties


    【解决方案1】:

    附加属性类中的那些“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
    }
    

    【讨论】:

    • 对不起大家,因为我的问题忽略了我想在后面的代码中捕获传入值的事实。对 Rob 的猜测是我所追求的额外荣誉。非常感谢 Rob。
    • 前段时间我也遇到过同样的问题,所以很容易猜到 :)
    • 想知道为什么 SetXXX 和 GetXXX 出现在 Internet 上博客的几乎所有 Attached Property 和 Behavior 示例中......
    • somethingsomethingArgs == DependencyPropertyChangedEventArgs per stackoverflow.com/questions/31701336(我认为?)
    【解决方案2】:

    使用类似的东西:

    public static readonly DependencyProperty HourTicksBrushProperty = DependencyProperty.RegisterAttached("HourTicksBrush", typeof(Brush), typeof(ClockFace), new FrameworkPropertyMetadata(Brushes.Black, FrameworkPropertyMetadataOptions.AffectsRender));
    
    
    public static Brush HourTicksBrush
    {
        get { return (Brush)GetValue(HourTicksBrushProperty); }
        set { SetValue(HourTicksBrushProperty); }
    }
    

    以及 XAML 中的类似内容

    <Controls:Clockface.HourTicks Fill="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=HourTicksBrush}/>
    

    我不确定是在 RelativeSource 中使用 TemplatedParent 还是 Self

    【讨论】:

    • 我的解释可能有误。我已经更新了我使用的 xaml。我对 xaml 没有问题...只是设置值不会触发 ClockFace 中的 SetHourTicksBrush 方法,因此不会更新 Brush。
    • 但是为什么当在父控件上设置时 Brush 属性没有更新,而在实际 ClockFace 控件上设置时它会更新?或者稍微改变一下问题......我怎样才能做到这一点?
    猜你喜欢
    • 1970-01-01
    • 2011-10-30
    • 1970-01-01
    • 2018-03-15
    • 1970-01-01
    • 1970-01-01
    • 2020-03-22
    相关资源
    最近更新 更多