Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to get a property value of an object using PropertyPath class?

Tags:

c#

.net

wpf

I want to get a value of a nested property of an object (something like Person.FullName.FirstName). I saw that in .Net there is a class named PropertyPath, which WPF uses for a similar purpose in Binding. Is there a way to reuse WPF's mechanism, or should I write one on my own.

like image 881
Andy Avatar asked May 18 '09 11:05

Andy


1 Answers

Reusing the PropertyPath is tempting as it supports traversing nested properties as you point out and indexes. You could write similar functionality yourself, I have myself in the past but it involves semi-complicated text parsing and lots of reflection work.

As Andrew points out you can simply reuse the PropertyPath from WPF. I'm assuming you just want to evaluate that path against an object that you have in which case the code is a little involved. To evaluate the PropertyPath it has to be used in a Binding against a DependencyObject. To demonstrate this I've just created a simple DependencyObject called BindingEvaluator which has a single DependencyProperty. The real magic then happens by calling BindingOperations.SetBinding which applies the binding so we can read the evaluated value.

var path = new PropertyPath("FullName.FirstName");

var binding = new Binding();
binding.Source = new Person { FullName = new FullName { FirstName = "David"}}; // Just an example object similar to your question
binding.Path = path;
binding.Mode = BindingMode.TwoWay;

var evaluator = new BindingEvaluator();
BindingOperations.SetBinding(evaluator, BindingEvaluator.TargetProperty, binding);
var value = evaluator.Target;
// value will now be set to "David"


public class BindingEvaluator : DependencyObject
{
    public static readonly DependencyProperty TargetProperty =
        DependencyProperty.Register(
            "Target", 
            typeof (object), 
            typeof (BindingEvaluator));

    public object Target
    {
        get { return GetValue(TargetProperty); }
        set { SetValue(TargetProperty, value); }
    }
}

If you wanted to extend this you could wire up the PropertyChanged events to support reading values that change. I hope this helps!

like image 192
David Padbury Avatar answered Oct 05 '22 16:10

David Padbury