在asp.net网站中动态加载用户控件(ascx)

Posted

技术标签:

【中文标题】在asp.net网站中动态加载用户控件(ascx)【英文标题】:Dynamically Load a user control (ascx) in a asp.net website 【发布时间】:2010-11-20 09:47:07 【问题描述】:

我正在尝试在 asp.web 站点中动态加载用户控件。但是由于 asp.net 网站项目的设置方式(我认为),我无法访问达到用户控件的类型定义。

我收到一条消息说我的类 HE_ContentTop_WebControl1 是:找不到他的类型或命名空间名称“HE_ContentTop_WebControl1”(您是否缺少 using 指令或程序集引用?)

知道如何使它起作用吗?我曾尝试使用命名空间,但在我看来,asp.net 网站在默认情况下并非旨在使用命名空间。我会对非命名空间方法感兴趣。

TIA

public partial class HE_Default :
     System.Web.UI.Page     

    protected void Page_Load(object sender, EventArgs e)  
      
       var control = (HE_ContentTop_WebControl1)Page.LoadControl("~/ContentTop/WebControl1.ascx");         
    

【问题讨论】:

不要忘记您还必须将加载的控件放在页面上的某个位置,例如占位符。 【参考方案1】:

假设控件与您的 Web 项目存在于同一个程序集中,您需要在 .aspx 文件中添加引用指令,

例如:

<%@ Reference Control="~/Controls/WebControl1.ascx">

请记住,IntelliSense 通常需要几分钟(或有时需要构建)才能获取此信息。

【讨论】:

非常感谢。如果我指向代码文件的位置,我假设不需要引用。添加文件似乎有点多余,但我又做了一个假设...... 如果您要处理大量用户控件,我真的不推荐这种方法。根据我的经验,将用户控件添加到命名空间然后动态加载它们的解决方案更加通用。 是的,这有点多余,但基本上参考指令是针对 ASP.NET 的,因此它实际上可以在适当的时间解决 Page.LoadControl 上的强制转换。很高兴我能帮上忙! 添加封闭标签 【参考方案2】:

使用命名空间可以轻松完成。这是一个例子:

WebControl1.ascx:

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="WebControl1.ascx.cs" Inherits="MyUserControls.WebControl1" %>

请注意,Inherits 引用了命名空间 (MyUserControls),而不仅仅是类名 (WebControl1)

WebControl1.ascx.cs:

namespace MyUserControls

    public partial class WebControl1 : System.Web.UI.UserControl
    
        protected void Page_Load(object sender, EventArgs e)
        

        
    

请注意,该类已包含在命名空间 MyUserControls 中

默认.aspx.cs:

using MyUserControls;

public partial class _Default : System.Web.UI.Page 

    protected void Page_Load(object sender, EventArgs e)
    
        var control = (WebControl1) Page.LoadControl("~/WebControl1.ascx");
    

这种方法可能允许您重新分发用户控件(或将它们保存在单独的项目中),而无需在 .aspx 文件中引用它们。

【讨论】:

这个 ascx 文件放在哪里?如果我把它放在任何我不能导入名称空间的地方,除非我把它放在 app_code 目录中。如果我把它放在 app_code 目录中,它会给我一个错误,你不能把它放在那里 不能导入命名空间是什么意思? 命名空间 MyUserControls .. 将 ascx 文件放在哪里(在 appcode 或 bin 中)。我把它放在控件文件夹中,但它不识别名称空间 MyUserControls。 赞成,因为这解决了 Visual Studio 和 MSBuild 中的问题。【参考方案3】:

网站模型不支持命名空间。因此,我无法让任何提议的解决方案发挥作用。但是,有一个解决方案。创建一个界面并将其放入应用程序代码中,然后在用户控件中实现该界面。您可以投射到界面上,它可以工作。

【讨论】:

谢谢,这帮助我在我工作的“网站”中实施了 Tchami 的解决方案。如您所说,我无法先引用该类,但是根据您对接口的解释和建议,它现在可以正常工作了!【参考方案4】:

这篇文章的主题有点误导。如果您只想动态添加控件,则不必引用该控件,因此您可以使用以下简单内容添加它:

protected void Page_Load(object sender, EventArgs e)

    Page.Controls.Add(Page.LoadControl("~/MyControl.ascx")); 

没有任何命名空间的麻烦。

【讨论】:

【参考方案5】:

引用不够用

<%@ Reference Control="~/Controls/WebControl1.ascx">

在 aspx 文件中只是答案的一部分。

您还需要在用户控件 aspx 文件中添加 calssName

<%@ Control ClassName="WebControl1" Language="C#" AutoEventWireup="true" CodeFile="WebControl1.ascx.cs" Inherits="AnySpaceName.DateSelector" %>

然后你可以在你的 aspx 文件中使用 userontrol

AnySpaceName.WebControl1 WC = (AnySpaceName.WebControl1)Page.LoadControl("~/WebControl1.ascx");    

【讨论】:

【参考方案6】:

以这种方式投射用户控件可能会产生很多问题。我的方法是创建一个类(比如控件类),将投射所需的所有属性和方法放入其中并从 System.Web.UI.UserControl 继承这个类.然后在你的用户控制代码文件中而不是 System.Web.UI.UserControl 用户这个控制类。

现在,当您需要强制转换时,请仅使用此类进行强制转换。它也将是轻型铸造。

【讨论】:

以上是关于在asp.net网站中动态加载用户控件(ascx)的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET用户自定义控件

如何在asp.net用户控件(ascx)中插入activex

在网格视图中的 ASCX 控件内的控件上使用 Javascript 显示隐藏。 (ASP.NET + Javascript)

Javascript 在 ASCX 中不起作用 – ASP NET 用户控件

ASCX 用户控制 SDL Tridion 2011

Asp.Net:用户控件中的寻呼机不分页