如何在ASP.NET网站中使用自定义控件?

时间:2013-05-28 13:14:12

标签: c# asp.net .net

我有一个 ASP.NET网站,而不是Web应用程序,我已经构建了一个自定义CompareValidator,它能够超出它自己的命名容器:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI.WebControls;
using System.Web.UI;

public class GlobalCompareValidator : CompareValidator
{
    new protected void CheckControlValidationProperty(string name, string propertyName)
    {
        Control control = this.Page.NamingContainer.FindControl(name);
        if (control == null)
        {
            throw new HttpException("Validator_control_not_found");
        }
        if (BaseValidator.GetValidationProperty(control) == null)
        {
            throw new HttpException("Validator_bad_control_type");
        }
    }
}

并且该代码存在于App_Code目录中。现在,我想在ASCX页面上使用这个新的自定义控件,如下所示:

<me:GlobalCompareValidator ID="compareValidator" CssClass="errorMessage" Display="None"
    EnableClientScript="false" Text="&nbsp;" ValidationGroup="LHError" runat="server" />

但是,在尝试注册程序集以使用它时:

<%@ Register TagPrefix="me" Namespace="MyNamespace" Assembly="MyAssembly" %>

我收到此错误:

  

无法加载文件或程序集“...”或其依赖项之一。系统找不到指定的文件。

现在,这并不是那么令人惊讶,因为ASP.NET网站并没有真正生成这样的程序集。但是,如果我将Assembly标记设置为关闭,则无法找到GlobalCompareValidator。当然,它可能无法使用Assembly标记找到它,但该错误可能因无法找到程序集而隐藏。

我如何获得可在ASP.NET网站中使用的自定义控件?

2 个答案:

答案 0 :(得分:1)

您可以将Register指令用于两个目的:

  1. 包含UserControl
  2. 包含自定义控件
  3. 只有在包含UserControl时才需要SRC属性。在您的情况下,您正在使用自定义控件,因此您只需要命名空间和程序集属性。

    您可以查看此MSDN页面以获取更多信息:

    http://msdn.microsoft.com/en-us/library/c76dd5k1(v=vs.71).aspx

答案 1 :(得分:1)

好吧,这个问题的解决方案是错综复杂的,但在这里。首先,在花费大量时间尝试使自定义控件工作之后,我决定改变我对问题的思考方式。我说:

  

如果我可以在正确的命名容器中获取控件怎么办?

似乎足够直接!在运行时,我们将从用户控件中删除控件并将其添加到用户控件的父级。但是,这比看起来更复杂。您更改了ControlsInit中的Load集合,因此这个想法有点问题。但是,唉,Stack Overflow来救援by way of the answer here!因此,我将以下代码添加到用户控件中:

protected void Page_Init(object sender, EventArgs e)
{
    this.Page.Init += PageInit;
}

protected void PageInit(object sender, EventArgs e)
{
    if (!string.IsNullOrEmpty(this.ControlToCompare))
    {
        this.Controls.Remove(this.compareValidator);
        this.Parent.Controls.Add(this.compareValidator);
    }
}

你在这里有一个页面生命周期中的一点漏洞。虽然我无法修改ControlsInit中的Load集合,但我可以在这两个事件之间进行修改!谢谢蒂姆!

这完成了任务,因为我能够在运行时将CompareValidator移动到正确的命名容器,以便它可以找到它正在验证的用户控件。

注意:您还必须将ValidationProperty属性添加到要与之比较的用户控件上。我是这样做的:

[ValidationProperty("Value")]

然后当然有一个名为Value的属性在该用户控件上公开。在我的情况下,该属性继续使用我为CompareValidator修改的相同用户控件,因为我正在比较来自同一用户控件的两个值。

我希望这有助于某人!