Question

I thought I would ask this question to see why many examples and people prefer to use inline databinding in the aspx code vs implementing an OnDataBinding event when using WebForms.

For any databound control (eg. Repeater, GridView, etc) I always implement the OnDataBinding method for field level controls if I need to do anything that isn't built in out of the box (eg. I need to do an Eval). Most examples I see have the code right in the aspx page using the inline <%# syntax.

Example of inline ASP.NET code:

<asp:Literal ID="litExample" runat="server"
    Text='<%# Eval("ExampleField").ToString() %>' />

Example of how I prefer to do it:

In the aspx:

<asp:Literal ID="litExample" runat="server" 
    OnDataBinding="litExample_DataBinding" />

In the codebehind .cs:

protected void litExample_DataBinding(object sender, System.EventArgs e)
{
    Literal lit = (Literal)(sender);
    lit.Text = string.Format("{1} - {2}",
        Eval("ExampleField").ToString(),
        Eval("ExampleField2").ToString());
}

I personally prefer the codebehind method because it keeps my aspx pages clean and I don't have all this inline code all over the place and the next guy just knows to always look in the .cs files for code changes. The seperation of presentation and code is also maintained better this way as the HTML is place holders only and the codebind is determining what is actually being put in control.

Now these are very basic examples. The field could be a integer that you want to format with leading 0s or a DateTime that needs a specific format etc. It could also take all sort of manipulation and code to get the finally value that should be stored in the 'Text' property at the end.

Where do you draw the line and move it to the codebehind if you are using inline code?

What are the pros and cons for doing it either way?

Does one take more overhead than the other?

Edit Note: I am not talking about assigning a value to a control that is just on the page but one that is being databound to because it exists in a repeater template or gridview item template etc... Obviously a literal sitting on a page you can just assign in code.

Edit Note: I thought I would gather more response, especially with regards to the overhead. Do most people NOT use the OnDataBinding events?

Was it helpful?

Solution

There's little performance difference between them. A data binding expression is parsed and compiles out to something like

control.DataBinding += new EventHandler(ControlDataBinding);

and also

private void ControlDataBinding(object sender, EventArgs e) {
    control.Text = Eval("Field");
}

In this case, the OnDataBinding method is not overridden. The base Control.OnDataBinding method is executed, which raises the DataBinding event, causing the above code to execute.

When you override OnDataBinding, you're simply taking over before the base code is run, and get to set the Text property yourself (for example).


I dislike giving out partial answers, but I'll do it this time because I think it's neat, and it saved me recently:

I said that the data binding expression are parsed. In fact, all of the markup is parsed, code in C#, VB.NET or whatever language is generated, and this is them compiled into a class. When the page is requested, an instance of this class is created, and it begins its life.

You can locate these generated code files on disk sorry, I don't remember where. The interesting thing about them is that they still work, as code.

For instance, I recently had some fairly complex Infragistics grids set up, had all the formatting complete, and then found that I needed to be able to set the formatting at rumtime (to get the correct format into exported Excel files). In order to do this, I opened the source file (all grids were in a single user control) and was able to extract the configuration of each grid into a separate group of methods.

I was able to clean them up with ReSharper, extract common code sequences into a base class, and was left with one static method to set up each grid. I was then able to call them both for the initial setup, and for the setup of the dummy grid used for Excel export.

OTHER TIPS

I much prefer the opposite. I prefer to keep my code-behind limited to procedural code, and keep all my declarative code in my Aspx page. In your example above, the literal is absolutely declarative and therefore (by my preference) would not belong in code-behind. Much more robust functionality generally goes in my code-behind, and I don't want my developers to be cluttered by having to sift through a bunch of initialization lines when trying to understand it.

I prefer it your way with OnDataBinding. You can keep your codebehind clean by using a "Databind" region for all the OnDataBinding calls, and you can keep your markup clean by getting those horrible server-side code blocks out of there.

I think most people do it the inline way because it's easier to understand and to implement.

Actually I prefer to use the aspx for controls that you would expect to Bind, like listview, gridview, repeater and other similar controls.

For the other controls, I would set them in the codebehind, but directly (as part of the process I am doing, instead of calling the literal.DataBind or DataBind for the whole page). If it is an user/custom control, that I expect the callers to do a DataBind, then I would override DataBind and set the values.

That said, I usually has plenty of code outside the codebehind, and have a call to something like ShowUser, where I put those assignments to controls (instead of setting a property, then doing a bind, and having all those evals for simple controls).

I agree with caltrop. I like my markup to be clean and all my aspx/ascx code to reside in my code-behind files (where it belongs).

I only have one thing to add. I prefer not to litter my code with OnDataBinding() events wired for each of my databound controls. Instead I do it all in the OnDataBinding() event of the User Control that is being embedded in the bindable-control (such as the repeater in your sample).

For example, in my User Control's code-behind you would find:

protected override void OnDataBinding(EventArgs e)
{
    base.OnDataBinding(e);

    litExample.Text = Eval("ExampleField") + " - " + Eval("ExampleField2");
}

From here you can set the properties of all your controls or call other methods to set them. Notice how, in my example, I didn't need to perform the boxing like you did here: Literal lit = (Literal)(sender);

That alone should save you on some performance (nanoseconds of course, but something worth measure). Read the section "Performance" here: http://msdn.microsoft.com/en-us/library/yz2be5wk%28v=vs.80%29.aspx

I am also at war with using strings in my code. I would have either used const string variables to define "ExampleField" and "ExampleField2" or set them up as public properties in the User Control that could then be set by the containing control/page based on the column name of the data object it will be bound against. This affords more flexibility and re-use of the control.

FYI: You don not need to call ToString() on Eval, as this method already returns a string.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top