Bra*_*AGr 11 c# wpf xaml dependency-properties wpftoolkit
是什么决定了同一控件上多个DepdencyProperties的评估顺序?
我正在使用Extended WPF Toolkit PropertyGrid并且绑定了SelectedObject和PropertyDefinitions:
<extToolkit:PropertyGrid AutoGenerateProperties="False" SelectedObject="{Binding ActiveDataPoint}" PropertyDefinitions="{Binding ActiveDataPoint.Properties}">
Run Code Online (Sandbox Code Playgroud)
问题是OnSelectedObjectChanged从依赖项属性触发,并且在该更改的处理程序中它引用了PropertyDefinitions,它被视为null.如果我注释掉OnSelectedObjectChanged处理程序,那么我可以看到调试OnPropertyDefinitionsChanged时调用OnSelectedObjectChanged.
public static readonly DependencyProperty PropertyDefinitionsProperty = DependencyProperty.Register( "PropertyDefinitions", typeof( PropertyDefinitionCollection ), typeof( PropertyGrid ), new UIPropertyMetadata( null, OnPropertyDefinitionsChanged ) );
public PropertyDefinitionCollection PropertyDefinitions
{
get
{
return ( PropertyDefinitionCollection )GetValue( PropertyDefinitionsProperty );
}
set
{
SetValue( PropertyDefinitionsProperty, value );
}
}
private static void OnPropertyDefinitionsChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
Console.Write("I changed!");
}
public static readonly DependencyProperty SelectedObjectProperty = DependencyProperty.Register( "SelectedObject", typeof( object ), typeof( PropertyGrid ), new UIPropertyMetadata( null, OnSelectedObjectChanged ) );
public object SelectedObject
{
get
{
return ( object )GetValue( SelectedObjectProperty );
}
set
{
SetValue( SelectedObjectProperty, value );
}
}
private static void OnSelectedObjectChanged( DependencyObject o, DependencyPropertyChangedEventArgs e )
{
PropertyGrid propertyInspector = o as PropertyGrid;
if( propertyInspector != null )
propertyInspector.OnSelectedObjectChanged( ( object )e.OldValue, ( object )e.NewValue );
}
Run Code Online (Sandbox Code Playgroud)
我在这个论坛帖子中讨论了我面临的问题,但是我想问一个更一般的WPF问题,即如何更改这些属性更新的顺序.
我试过在不同的订单中多次调用NotifyPropertyChanged,但这似乎并没有影响到这一点.我可以导致订单不同,还是应该修改PropertyGrid以便它可以用于任何一个订单?
Cod*_*ked 10
简短的回答是它都是一个黑盒子,你不应该依赖于在另一个之前或之后进行评估.因此,最好的方法是修改PropertyGrid,使其无论设置属性的顺序如何都可以工作.
答案很长,看起来它取决于绑定的指定顺序.所以你可以这样做:
<extToolkit:PropertyGrid AutoGenerateProperties="False"
PropertyDefinitions="{Binding ActiveDataPoint.Properties}"
SelectedObject="{Binding ActiveDataPoint}"
>
Run Code Online (Sandbox Code Playgroud)
代替:
<extToolkit:PropertyGrid AutoGenerateProperties="False"
SelectedObject="{Binding ActiveDataPoint}"
PropertyDefinitions="{Binding ActiveDataPoint.Properties}"
>
Run Code Online (Sandbox Code Playgroud)
再一次,依靠这个是不好的做法.并且这个怪癖可能仅适用于控件初始化时.对ActiveDataPoint或DataContext之后的更改可能会导致不同的顺序.
还有一个例子来证实已经说过的话
......永远不要依赖于所应用的属性的顺序
在定义的自UserControl定义DependencyProperty(.NET 4.5等)中 - 在初始化时调用PropertyChangedCallbacks ...
实际订单是从"定义后面的代码"(静态字段)的顺序确定的
......我猜这与注册顺序有关.
在某些其他情况下,订单取决于属性在XAML中的排列方式.