简体   繁体   中英

Assign C# Lambda Func in Aspx

I have a custom control where I want to expose a method as a property ( eg for custom validation );

public Func<bool> ValidateMatrixFunc { get; set; }

then in the page that contains this custom control I can use a delegate or lambda exp to assign on OnPreInit event of the page;

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

    ucMatrixTable.ValidateMatrixFunc = ValidateMatrix;
 }

and this works.

However, I think it would be more convenient to do this in aspx, as in:

<uc1:MatrixTable ID="ucMatrixTable" runat="server" ValidateMatrixFunc="ValidateMatrix" />

But this crashes with the following message:

Cannot create an object of type 'System.Func`1[[System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]' from its string representation 'ValidateMatrix' for the 'ValidateMatrixFunc' property.

So, I just wonder... and i wonder.. if some ninja knows the answer to this, or it is just one of those mysteries of life we ll never get.

You might want to expose your "ValidateMatrixFunc" property as an event instead. Why? it's more consistent with how controls are typically implemented. Also, events allow you to have multiple subscribers (event handlers) for a single event. While this might not be a typical use case, it does sometimes happen.

I've described below how I would implement this as an event:

Let's call the event "ValidatingMatrix".

Then you could write your ASPX markup like this:

<uc1:MatrixTable ID="ucMatrixTable" runat="server" OnValidatingMatrix="ValidateMatrix" />

Also, let's use the CancelEventHandler delegate instead of Func<bool> . This means that your ValidateMatrix method signature in your code-behind would have to look like this:

protected void ValidateMatrix(object sender, System.ComponentModel.CancelEventArgs e)
{
    // perform validation logic

    if (validationFailed)
    {
        e.Cancel = true;
    }
}

Inside of your MatrixTable custom control, implement something like this:

    const string ValidatingMatrixEventKey = "ValidatingMatrix";

    public event System.ComponentModel.CancelEventHandler ValidatingMatrix
    {
        add { this.Events.AddHandler(ValidatingMatrixEventKey, value); }
        remove { this.Events.RemoveHandler(ValidatingMatrixEventKey, value); }
    }

    protected bool OnValidatingMatrix()
    {
        var handler = this.Events[ValidatingMatrixEventKey] as System.ComponentModel.CancelEventHandler;
        if (handler != null)
        {
            // prepare event args
            var e = new System.ComponentModel.CancelEventArgs(false);

            // call the event handlers (an event can have multiple event handlers)
            handler(this, e);

            // if any event handler changed the Cancel property to true, then validation failed (return false)
            return !e.Cancel;
        }

        // there were no event handlers, so validation passes by default (return true)
        return true;
    }

    private void MyLogic()
    {
        if (this.OnValidatingMatrix())
        {
            // validation passed
        }
        else
        {
            // validation failed
        }
    }

It is interpretting the function name as a literal. Try using a databinding expression http://msdn.microsoft.com/en-us/library/bda9bbfx(v=vs.71).aspx

You will need to play with it, but here is a possible example:

<uc1:MatrixTable ID="ucMatrixTable" runat="server" ValidateMatrixFunc="<%# ValidateMatrix %>" />

ASP.NET uses TypeConverters to convert the string representation of a property value assigned via markup to convert the string to the correct type for the property. The error is telling you that there is no registered TypeConverter for the Func type. A TypeConverter has to be registered on the class itself so that's not something you could do, and in any case I don't think that it would allow you to achieve what you want anyway.

That approach doesn't work, but your underlying goal is very common: use EventHandlers instead of Funcs . See this MSDN article for more information: http://msdn.microsoft.com/en-us/library/system.eventhandler.aspx

Your "return" bool should be implemented instead in the event handler:

public void GetCurrentRecords(object sender, EventArgs e)
{
    var obj  = sender as Lcmp.Website.Data.Controls.AFTO95ViewerControl;
    obj.ValidateMatrixFunc = whatever;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM