tags:

views:

318

answers:

3

I have used ExpressionBuilders here and there within my asp.net markup to return simple data types.

Does anyone have any ideas how an ExpressionBuilder might be used to wire up an event inline? Or can ExpressionBuilders only return literals?

I would like to wire up the OnLoad event (or any event) by creating an ExpressionBuilder (named AutoBind in my example). Any ideas if this can be done?

<asp:DropDownList ID="DropDownList1" runat="server"
    DataSource='<%# GetRecords() %>'
    DataTextField="Name" DataValueField="ID"
    OnLoad="<%$ AutoBind: this.DataBind() %>" />
A: 

instead of using expression builder you can call any of the event method defined in your code which has the reuqired signature of event handler

in the event handle event arguments you can identify the object and data and manipulate control as you want

scorpio
Definately but the idea here is to do this in markup if possible.
Andrew Robinson
A: 

I think I understand what you're trying to do here, correct me if I'm wrong.

It looks like you want to code the actual handler itself as part of the expression, ie, when Load fires for the drop down list, you want DataBind() to be called.

It's simply not legal to use an expression in this context in the first place. Expressions can only be used for setting public properties on the control instance - OnLoad is not a public property but an event hook generated by the parser from the control's public events.

If you set any expression on an event hook such as OnLoad, you will get a compilation error like this: Type 'System.Web.UI.WebControls.DropDownList' does not have a public property named 'OnLoad'.

Also, expression builders don't just return literals - they return expressions, hence the name. An expression in this context means a CodeDom expression which represents code that will be executed when the page is executed, as part of the target property assignment.

For example, this ConnectionStrings expression:

<asp:Literal Text="<%$ ConnectionStrings: myConnection %>" />

returns a CodeDom expression that looks like this in a compiled page:

control.Text = ConnectionStringsExpressionBuilder.GetConnectionString("myConnection");

Sam
+2  A: 

Sam is correct. Expressions can only be set on properties, it will not wire an event. I got "close" by doing this with the expression builder.

[System.Web.Compilation.ExpressionPrefix("Delegate")]
    public class DelegateExpressionBuilder : ExpressionBuilder
    {
        public override CodeExpression GetCodeExpression(BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context)
        {           

         return new CodeDelegateCreateExpression(new CodeTypeReference("System.EventHandler"), null, entry.Expression);
        }
    }

In the mark of the page you would write something like this...

<asp:DropDownList runat="server" onload='<%$ Delegate:(o,e) => { this.DataBind(); } %>' />

The problem is that the compiler will generate this.

 ((System.Web.UI.IAttributeAccessor)(@__ctrl)).SetAttribute("onload", System.Convert.ToString(new System.EventHandler((o,e) => { this.DataBind(); }), System.Globalization.CultureInfo.CurrentCulture));

It's essentialy "converting" the delegate to a string and in reality you want the compiler to do this...

@__ctrl.Load += new System.EventHandler((o,e) => { this.DataBind(); });
Chad