3

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

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

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

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

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

4

4 回答 4

2

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

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

我们将事件称为“ValidatingMatrix”。

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

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

另外,让我们使用CancelEventHandler委托而不是Func<bool>. 这意味着您的代码隐藏中的 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
        }
    }
于 2011-11-18T19:30:15.257 回答
1

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

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

<uc1:MatrixTable ID="ucMatrixTable" runat="server" ValidateMatrixFunc="<%# ValidateMatrix %>" />
于 2011-10-13T11:13:46.527 回答
1

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

于 2011-10-13T11:36:59.087 回答
1

这种方法不起作用,但您的基本目标很常见:使用 EventHandlers 而不是 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;
}
于 2011-11-18T18:36:14.373 回答