Порядок оценки привязок DependencyProperties? - PullRequest
11 голосов
/ 17 марта 2012

От чего зависит порядок, в котором оцениваются несколько объектов DepdencyProperties на одном и том же элементе управления?

Я использую Extended WPF Toolkit PropertyGrid, и у меня есть привязки к SelectedObject и PropertyDefinitions:

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

Проблема в том, что OnSelectedObjectChanged запускается из свойства зависимостей, и в этом измененном обработчике он ссылается на PropertyDefinitions, который он видит как нулевой. Если я закомментирую обработчик 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 );
}

Проблема, с которой я сталкиваюсь, обсуждается в этой ветке форума , но я задаю более общий вопрос WPF о том, как изменить порядок обновления этих свойств.

Я пытался иметь несколько вызовов NotifyPropertyChanged в разных порядках, но это, похоже, не влияет на это. Могу ли я сделать так, чтобы порядок был другим или я должен просто изменить PropertyGrid, чтобы он работал для любого заказа?

Ответы [ 2 ]

10 голосов
/ 17 марта 2012

Краткий ответ: все это черный ящик, и вы не должны полагаться на то, что один из них оценивается до или после другого.Поэтому наилучшим подходом было бы изменить PropertyGrid, чтобы он работал независимо от порядка, в котором установлены свойства.

Длинный ответ заключается в том, что, похоже, все зависит от того, как указан порядок привязок.Таким образом, вы можете сделать:

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

Вместо:

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

Опять же, было бы плохой практикой полагаться на это.И эта причуда может работать только тогда, когда элемент управления инициализирован.Изменения на ActiveDataPoint или DataContext позднее могут привести к другому порядку.

8 голосов
/ 06 августа 2014

И еще один контрпример, подтверждающий сказанное.

... никогда не полагаться на порядок применения свойств

В пользовательском UserControl с определенными DependencyProperty -ies (.NET 4.5 и т. Д.) - как PropertyChangedCallbacks вызываются при инициализации ...

фактический порядок определяется из порядка «код за определениями» (статические поля)

... Я предполагаю, что это связано с порядком регистрации.

В некоторых других случаях порядок зависит от того, как свойства выстроены в XAML.

...