2010-02-06 4 views
10

J'écris un contrôle personnalisé, et j'ai un chemin de propriété en tant que chaîne (pensez comboBox.SelectedValuePath).
Quelle est la meilleure façon dans le code d'évaluer cette chaîne pour un objet arbitraire?WPF Comment évaluer un chemin de propriété?

Je peux évidemment juste l'analyser moi-même, mais c'est un hack, et je veux que le chemin prenne en charge tout ce que fait comboBox.SelectedValuePath (par souci de cohérence).

Résultat (grâce à Aran Mulholland):

Je ne sais pas sur les performances de cela, mais je ne me soucie pas beaucoup pour la performance en ce moment.

public class BindingEvaluator { 
    #region Target Class 

    private class Target : DependencyObject { 
     public static readonly DependencyProperty ResultProperty = DependencyProperty.Register(
      "Result", typeof(IEnumerable), typeof(BindingEvaluator) 
     ); 

     public object Result { 
      get { return this.GetValue(ResultProperty); } 
      set { this.SetValue(ResultProperty, value); } 
     } 
    } 

    #endregion 

    public object GetValue(object source, string propertyPath) { 
     var target = new Target(); 
     BindingOperations.SetBinding(target, Target.ResultProperty, new Binding(propertyPath) { 
      Source = source, 
      Mode = BindingMode.OneTime 
     }); 
     return target.Result; 
    } 
} 
+0

Est-il à noter que le type déclaré de DependencyProperty dans Target est IEnumerable lorsque la propriété Result est de type object? – dtm

+0

@dtm probablement juste mon erreur - version intermédiaire publiée au lieu de finale. mais c'était il y a longtemps et je ne m'en souviens pas. Si je trouve ce code, je vais corriger la question, sinon si vous l'avez testé, veuillez me le faire savoir. –

+0

J'ai implémenté quelque chose comme ça avec des types correspondants pour la propriété de dépendance et la propriété elle-même; cependant, et de façon surprenante, cela fonctionne toujours si je substitue IEnumerable à la place de Object dans DepedencyProperty.Register. Je ne sais pas quoi faire de cela ... – dtm

Répondre

6

Créer un objet qui a une propriété de dépendance de type objet, définissez la liaison dessus avec votre chemin de propriété comme le chemin, et votre objet arbitraire comme source. la liaison va s'exécuter et vous pouvez voir ce qui se trouve à la fin du chemin de la propriété. C'est le seul moyen que j'ai trouvé pour faire ce genre de chose dans le code. vous pourriez écrire un moteur de réflexion récursif qui pourrait suivre un chemin de propriété, mais c'est déjà fait, nous l'utilisons quand nous lions. Prenez cinq minutes pour écrire :)

+0

Merci, cela fonctionne, en ajoutant le code résultant de la question. –

+1

Je l'utilise aussi bien dans le cas bizarre, je m'interroge sur la performance, mais wpf utilise la liaison partout si un autre ... –

+1

WPF peut avoir la mise en cache en place, tandis que le code dans la forme actuelle ne fonctionne pas. Au moins mettre en cache la liaison entre plusieurs appels peut théoriquement être meilleur, mais je ne me soucie pas assez de vérifier à moins que je remarque le ralentissement. :) –

Questions connexes