0

我有一个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 网站的自定义控件?

4

2 回答 2

1

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

  1. 包括一个用户控件
  2. 包括自定义控件

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

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

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

于 2013-05-28T13:20:20.787 回答
1

好吧,这个问题的解决方案很复杂,但它就是这样。首先,在花费大量时间试图让自定义控件正常工作后,我决定改变我对问题的思考方式。我说:

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

似乎很直接!在运行时,我们将从用户控件中移除控件并将其添加到用户控件的父级。但是,这比看起来要复杂得多。您在or中更改修改Controls集合,因此这个想法有点问题。但是,唉,Stack Overflow 在这里得到了答案!因此,我将以下代码添加到用户控件中:InitLoad

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

您在这里遇到的是页面生命周期中的一个小漏洞。虽然我不能在or中修改Controls集合,但我可以在这两个事件之间修改它!谢谢蒂姆!InitLoad

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

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

[ValidationProperty("Value")]

然后当然有一个名为的属性Value暴露在该用户控件上。在我的情况下,该属性位于我正在修改的同一个用户控件上,CompareValidator因为我正在比较来自同一个用户控件的两个值。

我希望这对某人有帮助!

于 2013-05-28T20:18:44.407 回答