views:

68

answers:

4

I have a binding to an unknown source. All I have is the binding. I have no other way of looking at the bound object. I need to figure out the Type for the bound object, even if the value is null (this is where my problem is).

I was evaluating the binding by binding to an object and then using the object as a way to get the Type, but I need to know the type even if the value is null.

For instance, I have a class like so:

public class Customer{
  public string Name { get; set; }
  public int Age { get; set; }
}

Now, if I have a WPF control bind to any of those properties (let's assume they are dependency properties) I would like to get the type of the property, even if the value is null.

So, I have a custom control that now has a Binding object that represents {Binding Name} for instance. How can I get the type of the "bound object" using C#?

A: 

It should just be a matter of doing

MyCustomControl.DataContext != null ? MyCustomControl.GetType() : default(Type);
Steve Danner
I don't have a DataContext. In the scope of my evaluating code, I only have a Binding. I have to get the type of the object that the binding is pointing to (even if the value is null)
Phobis
A: 

I think

object.GetType().FullName will give you the full name of the type

is that what you looking for??

try something like below

Binding b = new Binding(); // i assume you have the reference of the binding

Assembly.GetAssembly(b.Source.GetType()).GetLoadedModules()[0].GetField(b.Path.Path).FieldType;
saurabh
No, I have a Binding only. I have to get the type of the object that the binding is pointing to (even if the value is null)
Phobis
A: 

If the value is null, there is no type to be gotten. If the binding is to a static resource defined in the App.xaml, you would literally have to parse the xaml file itself to find out the type, if it's defined in a class you would have to reflect it to find out the type.

If the binding is done in code, I don't think you can do this, because it could be bound to a null local variable which you wouldn't even be able to reflect out (or maybe you can but that would be way over my head). If the binding is defined in xaml, you could rationally parse out the xaml and try to follow the xaml path parsing the other xaml files and reflecting any properties for bindings that path into the code.

This would be an enormous pain and I am pretty certain whatever you're endgoal here is, could be accomplished without the ridiculous time this would take by doing something other than trying to identify the type even if it was null.

Jimmy Hoffa
I am binding to a property of an object. I'm just trying to find a way to access the PropertyInfo of the bound property (or something similar).
Phobis
@Phobis: I didn't figure you were binding to the property of a non-object, it's just a matter of how you track down that object. Tracking it down from the xaml then reflecting the type for it's properties may be doable, but if the binding is defined in code though, you may not have any way of doing it other than reflection that's borderline decompilation..
Jimmy Hoffa
+2  A: 

Are you willing to use reflection to get access to non-public members? If so, I think Binding has an internal method called CreateBindingExpression that returns a BindingExpression, which has a private member called _listener of internal type PropertyPathListener. That has an internal property called LeafType, which I believe is what you're looking for.

It's messy, requires trust, and is subject to failure in future versions of the Framework, but it might be the only way to get what you're looking for.

Gabe
Wow... Yep, that is it. I am not going to do that. Looks like I will only allow binding to a property by setting a "Property" string and "Source" object instead. Thanks though! :)
Phobis
+1, although you don't need to jump through hoops to get the `BindingExpression` - just use `BindingOperations.GetBindingExpression`. However, from there you will unfortunately need to resort to reflection in order to determine the type of the source property.
Kent Boogaart