ASP.NET 动态更改用户控件源

4

情景

我有一个使用主页面的ASP.Net Web项目。 这个主页面包含一个用户控件形式的菜单。 有时,我想动态更改它以使用不同类型的菜单用户控件。

注册用户控件的当前代码

<%@ Register TagPrefix="chase" TagName="topMenu"  Src="~/UserControls/TopMenu.ascx" %>

在body标签内部

 <div id="menuRow">
     <chase:topMenu runat="server" />
 </div>

问题

有没有办法在注册代码中动态更改“SRC”属性以使用不同的用户控件?!

非常感谢您的帮助。

编辑:

尝试了这段代码,但我收到了“无效转换异常”

TopMenu uh3 = (TopMenu)this.LoadControl("~/UserControls/TopMenu.ascx");
            menuRow.Controls.Add(uh3);

'无法将类型为“ASP.usercontrols_topmenu_ascx”的对象强制转换为类型“SwintonTaxiWeb.UserControls.TopMenu”'。


你必须转换已加载的控件吗?为什么不直接这样做:menuRow.Controls.Add(this.LoadControl("~/UserControls/TopMenu.ascx")); - James McCormack
6个回答

1

如果您需要,可以在运行时添加用户控件。

UserControls_header3 uh3 = (UserControls_header3)this.LoadControl(header3);
phHeaderControls.Controls.Add(uh3);

请问您能看到我上面的编辑吗?每当我尝试运行这段代码时,都会出现无效转换异常 :-( - Goober

0

是什么引起了动态变化?

你可以在服务器端的代码中很容易地完成这个任务。

在您的 .aspx 页面中,您可以添加:

<asp:Panel id="menuRow" runat="server">
</asp:Panel>

我在这里使用面板,因为它为控件提供了一个漂亮的容器,并在它们周围输出一个<div>标签。

然后在你的代码后台,你会有类似这样的东西:

// Determine correct user control to load
string pathToUserControl = DetermineTopMenu();

// Load the user control - calling LoadControl forces the correct lifcycle events
// to fire, and ensures the control is created properly.
var topMenu = LoadControl(pathToUserControl);

// Add the control to the menuRow panels control collection.
menuRow.Controls.Add(topMenu);

我假设您有某种方法来确定要显示哪个用户控件,并且您已经以一种生成用户控件路径相当简单的方式对它们进行了命名。我将该逻辑隐藏在方法调用DetermineTopMenu中,因为:

  1. 我不知道您使用的逻辑是什么
  2. 这使得测试、扩展等更容易。

有关LoadControl的更多信息,请查看文档


“DetermineTopMenu();” 是你编写的自定义方法,对吗? - Goober
确定顶部菜单将是您需要编写的自定义方法。这就是为什么我开始问“是什么导致了动态变化”的原因 - 您可能有一种方法来确定显示哪个用户控件,我只是建议您将其封装在一个单独的方法中。 - Zhaph - Ben Duguid

0

0
你可以尝试在页面上注册这两个用户控件,并根据需要进行隐藏或禁用。

我已经尝试过这种方法了,并且对于其他一些控件也起作用了,但是这是一个由别人构建的Web项目,我正在进行修改,但无法按照通常的方式工作... - Goober
无论如何,我相信您无法在运行时更改寄存器信息,因为这将太晚了。 我认为您需要查看一个场景,在那里两者都已注册,但只使用其中一个。 - dove
就像我说的一样,我非常喜欢你提到的方法,这也是我最初为其他修改所采用的方式,但是出于某种原因,我无法将此方法应用于此特定控件。它的设计非常糟糕,代码混乱等等。 - Goober

0
关于您遇到的 InvalidCastException 问题,也许这个 MSDN 页面 可以帮助您。您可以尝试在控件的 <%@ Control %> 标记中设置控件的类名。

0

如果您正在使用输出缓存,则LoadControl返回一个System.Web.UI.PartialCachingControl实例。然后,您可以通过其属性CachedControl访问缓存实例,必须将其强制转换为适当的UserControl派生类型。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接