I have been using Visual Studio’s Declarative WebForms programming model lately to quickly create Web-based form interfaces. As part of this process I have been making extensive use of control binding using the Eval() and Bind() statements, and in some cases even the old ASP Response.Write syntax. As part of my review, I will use this article to to go over the pros and cons of using either option.
As a general rule of thumb, both Eval() and Bind() work similarly for read operations but Bind() offers more functionality when binding controls to a data source for the full spectrum of Read/Write operations.
Eval() was introduced with ASP.NET 2.0 as a shortcut for the ASP.NET 1.1 DataBinder.Eval(Container.DataItem(“abc”)) and is a read operation, so you can populate a control’s value using the Eval() method, but that’s basically the extent of the binding. Any other form operations such as inserting or updating must then be manually (typically programmatically) defined and controlled.
Bind() on the other hand is a comprehensive two-way link between your control and your data source. If you Bind() a control value then it will automatically pass the value to your data source for operations such as reading, inserting, and updating data without the programmer needing to specify anything.
Interestingly: unlike Container.DataItem() , Eval() uses reflection, so your application will consume less resources if you find & replace your Eval() statements with Container.DataItem() calls. Bind() of course is even more comprehensive functionality-wise so its overhead is also greater when compared with Eval().
I frequently use GridView, FormView, and DetailsView controls, and find the Bind() functionality is best for use with these. The Visual Studio declarative programming model encourages the use of Bind() operations with TemplateFields controls since Bind() uses as storage mechanism behind the scenes for managing the communication between controls within your FormView and your data source parameters.
In contrast if you are populating your FormView controls using the Eval() method, then referencing the nested controls as parameters for your data source is a bit more of a chore, and is not intentionally supported via declarative databinding. I see many questions online about how to get Eval to work in a databound, Templated Control, but as I mentioned, this is not proper form and Microsoft wants the developer to use the Bind() function instead.
For some environments you will be able to use a workaround to reference nested controls as a data source parameter using the $ separator using the syntax: FormViewId$NextedControlId . However this does not work in other environments (ie: I am now using Visual Studio 2010 and an ASP.NET 4 Web site, and the $ separator syntax does not work there).
If you use Eval() methods with your FormView control then a good solution is to programmatically bind the parameters you wish to pass to your data source. For example when controlling a FormView update, you can grab and populate the data source parameters in a codebehind click event as follows:
Protected Sub btnSaveHeader_Click(sender As Object, e As System.EventArgs) SqlDSInfo.UpdateParameters("paramOne").DefaultValue = (CType(FVMainView.FindControl("tbSomeControl"), TextBox)).Text SqlDSInfo.Update() End Sub
Or for a GridView with Eval() populated nested controls you can populate the data source parameters in a codebehind RowUpdating event as follows:
Protected Sub GVInfo_RowUpdating(sender As Object, e As System.Web.UI.WebControls.GridViewUpdateEventArgs) SqlDSInfo.UpdateParameters("paramOne").DefaultValue = (CType(GVInfo.Rows(e.RowIndex).FindControl("ddlNestedList"), DropDownList)).SelectedItem.Value End Sub
I find that using programmatic binding works nicely, but tends to be less maintainable when someone takes over the code or a Web designer is asked to modify the form.
Also it’s good to note that with ASP.NET binding you can also call a publicly scoped method/variable using the <%# %> tags. This can be incredibly handy if you want to output the result of a computation to your form as in the example code below:
<ItemTemplate> <%# ComputeSomething(DateTime.Now – CType(Eval("TestDate"),DateTime) %> </ItemTemplate> <script runat="server"> Function ComputeSomething(ByVal tsTestDate As TimeSpan) As String ' Do Something Here End Function
Visual Studio permits very rapid development of Forms-based solutions using Declarative binding techniques. This can be extremely beneficial for both rapid development as well as for maintainability reasons. To properly use this technology is is important to have a good understanding of the uses of the binding options that Visual Studio provides via the Eval() and Bind() methods.
- ASP.NET Forums – #EVAL vs #BIND
- Chris McKenzie’s Blog – Declarative vs. Programmatic binding with the ASP .NET DataGrid
- MSDN .NET 4 – Data-Binding Expressions Overview
- MSDN .NET 2.0 – GridView Examples for ASP.NET 2.0: Working with TemplateFields
- BigResource.com – ASP.NET: C# – Getting Eval To Work In A Databound, Templated Custom Control?