2010-08-26 4 views
13

si j'ai un objet appelé MyObject, qui a une propriété appelée MyChild, qui possède elle-même une propriété appelée Name. Comment puis-je obtenir la valeur de cette propriété Name si tout ce que j'ai est un chemin de liaison (c'est-à-dire "MyChild.Name"), et une référence à MyObject?WPF - Obtention d'une valeur de propriété à partir d'un chemin de liaison

MyObject 
    -MyChild 
    -Name 
+0

Pouvez-vous donner un exemple de la façon dont vous souhaitez utiliser cette ? – Rachel

Répondre

19

J'ai trouvé un moyen pour faire cela, mais c'est assez moche et probablement pas très rapide ... Fondamentalement, l'idée est de créer une liaison avec le chemin donné et de l'appliquer à une propriété d'un objet de dépendance. De cette façon, la liaison fait tout le travail de récupération de la valeur:

public static class PropertyPathHelper 
{ 
    public static object GetValue(object obj, string propertyPath) 
    { 
     Binding binding = new Binding(propertyPath); 
     binding.Mode = BindingMode.OneTime; 
     binding.Source = obj; 
     BindingOperations.SetBinding(_dummy, Dummy.ValueProperty, binding); 
     return _dummy.GetValue(Dummy.ValueProperty); 
    } 

    private static readonly Dummy _dummy = new Dummy(); 

    private class Dummy : DependencyObject 
    { 
     public static readonly DependencyProperty ValueProperty = 
      DependencyProperty.Register("Value", typeof(object), typeof(Dummy), new UIPropertyMetadata(null)); 
    } 
} 
+0

Cela ressemble à beaucoup de machines pour obtenir la valeur d'une liaison, mais je ne peux pas penser à une meilleure solution de code à usage général. +1 et Bravo. – Berryl

+0

Excellent, merci Thomas! La raison pour laquelle j'ai besoin de quelque chose comme ceci est parce que j'ai écrit une extension de balisage personnalisée pour le chargement des images. Cette extension a une propriété Name pour le nom de l'image, que je veux maintenant lier à une propriété de modèle dans un DataTemplate qui utilise l'extension de balisage. Cependant, je ne peux pas lier parce que le nom n'est pas un DP, ni peut-il être :(C'était la seule solution que je pouvais penser, donc je vais essayer ce code – devdigital

+0

Cela fonctionne parfaitement pour mes besoins (obtenir et définir la valeur d'une propriété d'un modèle de vue donné un chemin de liaison.) Y at-il une manière similaire d'obtenir le _type_ de la propriété qui serait liée avec un chemin de liaison donné – lesscode

0

ne sais pas ce que vous voulez faire, mais et comment (XAML ou code) mais vous pouvez toujours nommer votre objet

<MyObject x:Name="myBindingObject" ... /> 

un puis utilisez dans le code

myBindingObject.Something.Name 

ou en xaml

<BeginStoryboard> 
<Storyboard> 
    <DoubleAnimation 
     Storyboard.TargetName="myBindingObject" 
     Storyboard.TargetProperty="Background" 
     To="AA2343434" Duration="0:0:2" > 
    </DoubleAnimation> 
</Storyboard> 
</BeginStoryboard> 
3

J'ai développé un nuget packagePather.CSharp qui fait exactement ce dont vous avez besoin.

Il contient une classe Resolver qui a une méthode Resolve qui se comporte comme la méthode GetValue de @ ThomasLevesque.
Exemple:

IResolver resolver = new Resolver(); 
var o = new { Property1 = Property2 = "value" } }; 
var path = "Property1.Property2";  
object result = r.Resolve(o, path); //the result is the string "value" 

Il soutient même collection accès via l'index ou accès au dictionnaire via la touche.
chemins Exemple pour ceux-ci sont:

"ArrayProperty[5]" 
"DictionaryProperty[Key]" 
+0

Prend en charge l'accès aux propriétés d'interface et aux propriétés masquées explicitement implémentées? – Grx70

+0

@ Grx70 Oui. Cela fonctionne par réflexion, donc si la propriété existe sur l'objet et est publique, elle aura sa valeur. – Domysee

0

Je le fais de cette façon. S'il vous plaît laissez-moi savoir si cela est une très mauvaise idée, comme C# est juste un travail de côté pour moi, donc je ne suis pas un expert objectToAddTo est de type ItemsControl:

BindingExpression itemsSourceExpression = GetaBindingExression(objectToAddTo); 
object itemsSourceObject = (object)itemsSourceExpression.ResolvedSource; 
string itemSourceProperty = itemsSourceExpression.ResolvedSourcePropertyName; 

object propertyValue = itemsSourceObject.GetType().GetProperty(itemSourceProperty).GetGetMethod().Invoke(itemsSourceObject, null); // Get the value of the property 
Questions connexes