在依赖项属性的值源更改时获取通知

时间:2014-01-20 09:09:37

标签: c# wpf dependency-properties

是否有办法在依赖项属性的值源更改时获取通知?

我创建了一个附加属性,用于设置将值继承到子元素的标签:

LabelProperty = DependencyProperty.RegisterAttached ("Label", typeof (string), typeof (Class1), 
            new FrameworkPropertyMetadata (null, FrameworkPropertyMetadataOptions.Inherits, OnLabelChanged));

我将一个值设置为父元素上的Label属性,有效地将其应用于所有子元素。在某些时候,子元素设置与附加属性的本地值相同的值(在XAML中)。虽然该值实际上并未发生更改,但值源会从继承更改为本地

有没有办法在价值源中捕获这些变化?

2 个答案:

答案 0 :(得分:0)

当优先级发生变化时,没有像回调这样的事情。

但是,您始终可以使用DependencyPropertyHelper类来询问当前优先级。

http://msdn.microsoft.com/en-us/library/system.windows.dependencypropertyhelper.getvaluesource%28v=vs.110%29.aspx

http://msdn.microsoft.com/en-us/library/system.windows.valuesource%28v=vs.110%29.aspx

如果通过本地属性设置器设置了值,则可以附加自定义逻辑,表明您在本地调用了SetValue。我希望这会对你有所帮助。

修改

要追踪任何值设置,您可以订阅强制。

    public static int GetMyProperty(DependencyObject obj)
    {
        return (int)obj.GetValue(MyPropertyProperty);
    }

    public static void SetMyProperty(DependencyObject obj, int value)
    {
        obj.SetValue(MyPropertyProperty, value);
    }

    // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty MyPropertyProperty =
        DependencyProperty.RegisterAttached("MyProperty", typeof(int), typeof(MainWindow), new UIPropertyMetadata(0, null, delegate(DependencyObject o, object value) { /*do something here*/ return value; }));

答案 1 :(得分:0)

首先,感谢开发hedgehog的帮助。

在深入研究这个问题几天后,我不相信这种情况有解决方案。当值的源从 Inherits 更改为 Local 时(如果有人找到方法),我无法找到导致WPF引发属性更改事件的方法,我会很高兴知道的。)

首先使用Coerce机制的方向看起来很有希望,所以我尝试做这样的事情:

private static object CoeracLabel (DependencyObject d, object value)
{
    LabelProperty.DefaultMetadata.PropertyChangedCallback (d, new DependencyPropertyChangedEventArgs (LabelProperty, value, value));
    return value;
}

但是在摆弄这种方法半小时之后我也不得不丢弃它,因为当调用强制方法时,值源还没有更新,所以我不能运行任何依赖它的逻辑。

鉴于此,我决定更改解决方案并删除属性值继承。现在创建依赖项属性时没有 Inherits 标志,并且在in属性中更改了回调,我尝试查找具有不同值的父元素。

string parentLabel = GetParentLabel (d);
.
.

private static string GetParentLabel (DependencyObject child)
    {
        string parentLabel = null;

        child = LayoutHelper.GetParent (child, false);

        LayoutHelper.FindLayoutOrVisualParentObject (child, x =>
        {
            string label = GetLabel (x);
            if (!String.IsNullOrEmpty (label))
            {
                parentLabel = label;
                return true;
            }

            return false;
        }, true);

        return parentLabel;
    }