views:

426

answers:

3

I have yet to find a "nice" way to do two way databinding in .Net.
The one thing I don't like for example in the present asp.net two way databinding is doing the binding in the aspx page is no compile time checking, ie:

<asp:TextBox ID="TitleTextBox"
            runat="server"            Text='<%# Bind("Title_oops_spelled_wrong") %>'>

I would like to have something like this:

Class Binder
Public Sub BindControl(ctl As Control, objectProperty As ???????)
  '// Add ctl and objectProperty to a collection

End Sub

What I don't know is possible is, how to receive the objectProperty in my example; I want to receive a reference (ie: a pointer) to the property, so later, via this reference, I can either read from or write to the property.

Can this somehow be done with delegates perhaps??

UPDATE:
Note, I want to add the control reference to a binding collection, this collection would then be used for binding and unbinding.

A: 

The Bind is not a method and there is no some object behind the scene holding binding relationship. It's just a "magic" word that page parser uses to generate code behind. Essentially, it translates into Eval and control building code. The Eval, on the other hand, will use reflection to access bound item's properties.

If I understand correctly what you want, read-only property binding already works. Assuming you have a property Title in your class:

<asp:TextBox ID="TitleTextBox" runat="server" Text='<%# Title %>' />

For two-way binding, you'd have to either create your own Template or reflect existing one and pass the ExtractTemplateValuesMethod method and assign the DataBinding event to your control. This is where .NET uses Eval, which you'd replace with the property assignment.

In my opinion, that is what the DataBinding event is for.

However, if you question is more about whether one can have a reference to a property, then I'm afraid not. There is no property per say. You have to methods (get and set) and an entry in the metadata. You could store a reference to the object and property name, but then you'd have to use reflection.

You could use the delegates, but that would take you back to the same code as the one .NET generates, which is defining ExtractTemplateValuesMethod and doing DataBinding anyhow.

Ruslan
A: 

One solution would be to pass objectProperty ByRef.

If you want compile time type checking you would need to overload BindControl for any types that you plan on using. For example:

Public Sub BindControl(ctl As ITextControl, ByRef objectProperty As String)
    objectProperty = ITextControl.Text
End Sub

Public Sub BindControl(ctl As ITextControl, ByRef objectProperty As Integer)
    Integer.TryParse(TextControl.Text, objectProperty)
End Sub
..
Seth Reno
+1  A: 

Is there a reason that you want to avoid using the .NET data binding mechanism? It handles keeping parity between the control's value and the class's property value already, and provides rich design-time support.

You can interface with the data binding engine in two ways: either programatically or through the designer. To do basic data binding programatically is trivial. Say I have a class named "FooClass" with a string property named "MyString". I have a TextBox named myTxtBox on a form with an instance of FooClass called foo and I want to bind it to the MyString property:

myTxtBox.DataBindings.Add("Text", foo, "MyString");

Executing this will cause updates to the TextBox to get assigned to the property, and changes to the property from elsewhere will be reflected in the TextBox.

For more complex data binding scenarios, you'll probably want to create an Object Data Source in your project and put a BindingSource on your form. If you need help with specific steps in creating the data source I can help, but in general you'll create the source in your project and select the class to which you want to bind. You can then place a BindingSource on your form, point it at your object project data source, then use the Visual Studio designer to bind properties for your controls to properties on your object. You then set the DataSource property in your code to an instance of the class or collection to which you want to bind.

As a side note, as far as I am aware there is no "property delegate", as properties are actually function pairs (a get_ and a set_).

UPDATE:

As I read your comments, I'd like to point out that .NET data binding, even at the control level, does NOT automatically use reflection. Data binding is built around type descriptors and property descriptors, both for the bound control and the data source. It's true that if one or both of these sides does not implement specific property and type description then reflection will be used, but either side is more than free to provide its own description profile which would NOT use reflection.

Adam Robinson