是否有办法在依赖项属性的值源更改时获取通知?
我创建了一个附加属性,用于设置将值继承到子元素的标签:
LabelProperty = DependencyProperty.RegisterAttached ("Label", typeof (string), typeof (Class1),
new FrameworkPropertyMetadata (null, FrameworkPropertyMetadataOptions.Inherits, OnLabelChanged));
我将一个值设置为父元素上的Label属性,有效地将其应用于所有子元素。在某些时候,子元素设置与附加属性的本地值相同的值(在XAML中)。虽然该值实际上并未发生更改,但值源会从继承更改为本地。
有没有办法在价值源中捕获这些变化?
答案 0 :(得分:0)
当优先级发生变化时,没有像回调这样的事情。
但是,您始终可以使用DependencyPropertyHelper类来询问当前优先级。
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;
}