WebForms内容页如何获取Site.Master中的sbHome服务器控件?
解决WebForms内容页获取Master页嵌套服务器控件的问题
问题原因
Master.FindControl()只能查找直接属于Master页命名容器的子控件,你的<a>元素嵌套在普通<li>(非服务器控件)中,属于Master页的深层嵌套控件,直接调用Master.FindControl("sbHome")会返回null。
解决方案
方法1:使用递归查找控件
写一个通用的递归查找方法,遍历所有控件层级定位目标控件:
// 内容页后台代码 protected void Page_Load(object sender, EventArgs e) { HtmlGenericControl aControl = FindControlRecursive(Master, "sbHome") as HtmlGenericControl; if (aControl != null) { // 直接覆盖class属性,或追加active样式(避免清空原有必要样式) aControl.Attributes["class"] = "dropdown-toggle no-arrow active"; } } // 递归查找控件的辅助方法 private Control FindControlRecursive(Control root, string id) { if (root.ID == id) return root; foreach (Control child in root.Controls) { Control foundControl = FindControlRecursive(child, id); if (foundControl != null) return foundControl; } return null; }
方法2:在Master页定义公共属性暴露控件
在Site.Master的后台代码中,给目标控件定义一个公共属性:
// Site.Master.cs public HtmlGenericControl SbHomeLink { get { return sbHome; } }
然后在内容页后台直接访问该属性,若未指定Master类型,需在Dashboard.aspx顶部添加MasterType声明:
<%@ MasterType VirtualPath="~/Site.Master" %>
内容页后台代码:
// Dashboard.aspx.cs protected void Page_Load(object sender, EventArgs e) { if (Master.SbHomeLink != null) { Master.SbHomeLink.Attributes["class"] = "dropdown-toggle no-arrow active"; } }
方法3:将父容器设为服务器控件
把包裹<a>的<li>设置为服务器控件,先找到父容器再定位内部的<a>:
修改Site.Master中的代码:
<li runat="server" id="liHome"> <a runat="server" id="sbHome" href="Dashboard.aspx" class="dropdown-toggle no-arrow"> <span class="micon bi bi-house"></span><span class="mtext">Home</span> </a> </li>
内容页后台代码:
protected void Page_Load(object sender, EventArgs e) { HtmlGenericControl liControl = Master.FindControl("liHome") as HtmlGenericControl; if (liControl != null) { HtmlGenericControl aControl = liControl.FindControl("sbHome") as HtmlGenericControl; if (aControl != null) { aControl.Attributes["class"] = "dropdown-toggle no-arrow active"; } } }
内容的提问来源于stack exchange,提问作者Milo
相关产品推荐
相关产品推荐

