【问题标题】:Assign C# Lambda Func in Aspx在 Aspx 中分配 C# Lambda 函数
【发布时间】:2011-10-13 10:56:56
【问题描述】:

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

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" />

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

无法从其字符串表示形式 'ValidateMatrix' 中创建类型为 'System.Func`1[[System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]' 的对象'ValidateMatrixFunc' 属性。

所以,我只是想知道......我想知道......是否有忍者知道这个问题的答案,或者这只是我们永远不会得到的生活奥秘之一。

【问题讨论】:

    标签: c# asp.net delegates func


    【解决方案1】:

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

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

    我们将事件称为“ValidatingMatrix”。

    然后你可以这样写你的 ASPX 标记:

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

    另外,让我们使用CancelEventHandler 委托而不是Func&lt;bool&gt;。这意味着您的代码隐藏中的 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
            }
        }
    

    【讨论】:

    • Func 和 event 在概念上是不同的。发生某事时会引发事件,而funcpredicate 可用于过滤掉某事。如果您使用事件进行过滤,这是不自然或不恰当的。诚然,在 OP 的示例中,事件听起来更好。
    【解决方案2】:

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

    你需要玩它,但这里有一个可能的例子:

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

    【讨论】:

    • 谢谢..“它正在将函数名解释为文字”duhh..但我也无法让绑定在 aspx 上工作。
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      这种方法行不通,但您的基本目标很常见:use EventHandlers instead of Funcs。有关详细信息,请参阅此 MSDN 文章:http://msdn.microsoft.com/en-us/library/system.eventhandler.aspx

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

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

      【讨论】:

        猜你喜欢
        • 2017-12-08
        • 1970-01-01
        • 2013-04-06
        • 2012-06-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-01-13
        相关资源
        最近更新 更多