是否评估了DependencyProperties绑定的顺序?

时间:2012-03-16 20:52:19

标签: c# wpf xaml dependency-properties wpftoolkit

什么决定了同一控件上多个DepdencyProperties的评估顺序?

我正在使用Extended WPF Toolkit PropertyGrid并且绑定了SelectedObject和PropertyDefinitions:

<extToolkit:PropertyGrid AutoGenerateProperties="False" SelectedObject="{Binding ActiveDataPoint}" PropertyDefinitions="{Binding ActiveDataPoint.Properties}">

问题是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 );
}

我在this forum thread上讨论了我面临的问题,但我想问一个更普遍的WPF问题,即如何更改这些属性的更新顺序。

我试过在不同的订单中多次调用NotifyPropertyChanged,但这似乎并没有影响到这一点。我是否可以使订单不同,或者我应该只修改PropertyGrid以使其适用于任何订单?

2 个答案:

答案 0 :(得分:10)

简短的回答是,它完全是一个黑盒子,你不应该依赖于在另一个之前或之后进行评估。因此,最好的方法是修改PropertyGrid,使其无论设置属性的顺序如何都可以工作。

长的答案看起来它取决于绑定的指定顺序。所以你可以这样做:

<extToolkit:PropertyGrid AutoGenerateProperties="False"
    PropertyDefinitions="{Binding ActiveDataPoint.Properties}"
    SelectedObject="{Binding ActiveDataPoint}"
    >

而不是:

<extToolkit:PropertyGrid AutoGenerateProperties="False"
    SelectedObject="{Binding ActiveDataPoint}"
    PropertyDefinitions="{Binding ActiveDataPoint.Properties}"
    >

再次,依靠这一点是不好的做法。并且这个怪癖可能仅适用于控件初始化时。稍后对ActiveDataPointDataContext的更改可能会导致订单不同。

答案 1 :(得分:8)

还有一个例子来确认已经说过的话

  

...永远不要依赖正在应用的属性的顺序

在定义UserControl的自定义DependencyProperty中 - (.NET 4.5等) - 在初始化时调用PropertyChangedCallbacks ...

实际订单是根据“定义背后的代码”(静态字段)的顺序确定的

......我猜这与注册顺序有关。

在其他一些情况下,订单取决于属性在XAML中的排列方式。