I have a simple class with a property
class Foo
{
string Title { get; set; }
}
I am trying to simplify data binding by calling a function like
BindToText(titleTextBox, ()=>foo.Title );
which is declared like
void BindToText<T>(Control control, Expression<Func<T>> property)
{
var mex = property.Body as MemberExpression;
string name = mex.Member.Name;
control.DataBindings.Add("Text", ??? , name);
}
so what do I put in ???
for the instance of my Foo
class. How do I get a refernce to the calling foo
instance from the lambda expression?
edit:
The instance should be there somewhere because I can call property.Compile()
and create a delegate that uses the foo
instance inside my BindToText
function. So my question is if this can be done without adding a reference to the instance in the function parameters. I call upon Occum's Razor to yield the simplest solution.
edit 2:
What many have failed to notice is the closure that exists in accessing the instance of foo
inside my function, if I compile the lambda. How come the compiler knows where to find the instance, and I don't? I insist that there has to be an answer, without having to pass an extra argument.
Solution
Thanks to VirtualBlackFox the solution is such:
void BindText<T>(TextBoxBase text, Expression<Func<T>> property)
{
var mex = property.Body as MemberExpression;
string name = mex.Member.Name;
var fex = mex.Expression as MemberExpression;
var cex = fex.Expression as ConstantExpression;
var fld = fex.Member as FieldInfo;
var x = fld.GetValue(cex.Value);
text.DataBindings.Add("Text", x, name);
}
which alows me to simply type BindText(titleText, () => foo.Title);
.
Don't. Just modify the method to take another parameter, as described in #3444294. For your example, it may be something like this:
and would be called like
Still nice, but easy to understand. There's no magic happening. ;)
Small LINQPad sample of what you want :
Well, this is similar in tone to Hangy's solution, but is I think rather comfortable to use and does not require much magic:
This is basically an extension method that can be called on any object acting as source. It gives you back a Binding for a Text property which you can add to any Bindings collection.
Something like the following should work:
Let me know if that doesn't work for you.