在 Aspx 中分配 C# Lambda 函数

发布于 2024-12-09 09:15:58 字数 819 浏览 0 评论 0原文

我有一个自定义控件,我想将方法​​公开为属性(例如用于自定义验证);

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

然后在包含此自定义控件的页面中,我可以使用委托或 lambda exp 来分配页面的 OnPreInit 事件;

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

    ucMatrixTable.ValidateMatrixFunc = ValidateMatrix;
 }

这有效。

但是,我认为在 aspx 中执行此操作会更方便,如下所示:

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

但这会崩溃并显示以下消息:

Cannot create an object of type 'System.Func`1[[System.Boolean, mscorlib, Version =4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]' 来自其字符串表示形式“ValidateMatrix” 'ValidateMatrixFunc' 属性。

所以,我只是想知道……我想知道……是否有忍者知道这个问题的答案,或者这只是我们永远无法得到的生活之谜之一。

I have a custom control where I want to expose a method as a property ( e.g. 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

夏末染殇 2024-12-16 09:15:58

您可能希望将“ValidateMatrixFunc”属性公开为事件。为什么?它与通常实施控制的方式更加一致。此外,事件允许您为单个事件拥有多个订阅者(事件处理程序)。虽然这可能不是典型的用例,但有时确实会发生。

我在下面描述了如何将其实现为一个事件:

让我们将该事件称为“ValidatingMatrix”。

然后,您可以像这样编写 ASPX 标记:

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

另外,让我们使用 CancelEventHandler 委托而不是 Func。这意味着您的代码隐藏中的 ValidateMatrix 方法签名必须如下所示:

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

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

在 MatrixTable 自定义控件内部,实现如下所示的内容:

    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
        }
    }

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
        }
    }
呆萌少年 2024-12-16 09:15:58

它将函数名称解释为文字。尝试使用数据绑定表达式
http://msdn.microsoft.com/en- us/library/bda9bbfx(v=vs.71).aspx

您需要使用它,但这里是一个可能的示例:

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

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 %>" />
独自←快乐 2024-12-16 09:15:58

ASP.NET 使用 TypeConverters 来转换通过标记分配的属性值的 string 表示形式,用于将 string 转换为属性的正确类型。该错误告诉您没有为 Func 类型注册的 TypeConverterTypeConverter 必须在类本身上注册,因此这不是您可以做的事情,并且无论如何我认为它不会让您实现您想要的目标。

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.

任谁 2024-12-16 09:15:58

这种方法不起作用,但您的基本目标非常常见: 使用EventHandlers而不是Funcs。有关详细信息,请参阅此 MSDN 文章:http://msdn.microsoft。 com/en-us/library/system.eventhandler.aspx

您的“return”布尔值应该在事件处理程序中实现:

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

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文