tags:

views:

220

answers:

3

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.

A: 

I don't see any reason why you couldn't reuse it.

See PropertyPath:

Implements a data structure for describing a property as a path below another property, or below an owning type. Property paths are used in data binding to objects, and in storyboards and timelines for animations.

Andrew Hare
+2  A: 

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!

David Padbury
How would you write back to that property?
Aaron Fischer
I've just updated the code sample to include Updating the target. You just have to ensure the Binding is TwoWay and provide a setter.
David Padbury
A: 

You could use DataBinder.Eval() (from System.Web assembly) method which does just that, or use WPF objects as pointed out Here

Amittai Shapira