2013-05-28 59 views
0

我有一个ASP.NET网站,而不是Web应用程序,我已经建立了一个自定义CompareValidator这是能够获得它自己的命名容器的外面的:如何让自定义控件可用于ASP.NET网站?

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

我得到这个错误:

Could not load file or assembly '...' or one of its dependencies. The system cannot find the file specified.

现在,这并不是真的那么令人惊讶,因为ASP.NET网站并没有真正生成这样的程序集。但是,如果我将Assembly标签关闭,则无法找到GlobalCompareValidator。当然,它也可能找不到Assembly标签,但是这个错误很可能隐藏在找不到组件的事实中。

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

回答

1

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

What if I could get the control in the right naming container instead?

似乎挺直的!在运行时,我们将从用户控件中删除控件并将其添加到用户控件的父级控件。但是,这比看起来更复杂。您可以修改InitLoad中的Controls集合,这对于这个想法有点问题。但是,唉,堆栈溢出来救援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); 
    } 
} 

你这里是什么在页面生命周期的一个小漏洞。虽然我无法修改InitLoad中的Controls集合,但我可以在这两个事件之间修改它!谢谢蒂姆!

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

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

[ValidationProperty("Value")] 

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

我希望这可以帮助别人!

1

可以使用Register指令有两个目的:

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

如果你包括用户控件时,才需要SRC属性。就你而言,你使用的是自定义控件,所以你只需要命名空间和Assembly属性。

可以为更多信息,请这个MSDN页:

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