ASP.NET母版页 - 必不可少的东西。
但是,我的项目中有很多非常相似的UserControl - 它可能是AJAX ModalPopup的标准布局,或更多涉及的内容。
我希望我可以使用一些Master UserControl来摆脱我的一些重复代码(包括ascx文件和代码隐藏)。
有没有人有任何方法可以达到这个目的?
答案 0 :(得分:4)
这是一个古老的问题,但对于偶然发现这一点的人来说,我有一个强大的解决方案。
在app_code中,创建一个文件并粘贴此代码:
namespace MasterControls
{
// code written by alexander taylor on 2011-08-22. http://www.alexsapps.com
public abstract class ChildUserControl : UserControl
{
Control master;
public abstract string MasterControlVirtualPath { get; }
protected override void OnInit(EventArgs e)
{
master = LoadControl(MasterControlVirtualPath);
Controls.Add(master);
base.OnInit(e);
}
protected override void Render(HtmlTextWriter writer)
{
master.RenderControl(writer);
}
}
public class ControlContentPlaceHolder : Control
{
protected override void Render(HtmlTextWriter writer)
{
ControlContent found = null;
foreach (Control c in NamingContainer.NamingContainer.Controls)
{
ControlContent search;
search = c as ControlContent;
if (search != null && search.ControlContentPlaceHolderID.Equals(ID))
{
found = search;
break;
}
}
if (found != null)
{
//write content of the ContentControl
found.RenderControl(writer);
}
else
{
//use default content
base.Render(writer);
}
}
}
public class ControlContent : Control
{
public string ControlContentPlaceHolderID { get; set; }
}
}
示例“主控制”(相当于母版页)
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="MasterControl1.ascx.cs" Inherits="MasterControl1" %>
<%@ Register Namespace="MasterControls" TagPrefix="masterControls" %>
<p>content 1 below:<br />
<masterControls:ControlContentPlaceHolder ID="myContent1" runat="server">
default content 1 here!
</masterControls:ControlContentPlaceHolder></p>
<p>content 2 below:<br />
<masterControls:ControlContentPlaceHolder ID="myContent2" runat="server">
default content 2 here!
</masterControls:ControlContentPlaceHolder></p>
示例“子控件”(相当于页面)
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="ChildControl1.ascx.cs" Inherits="Control1" %>
<%@ Register Namespace="MasterControls" TagPrefix="masterControls" %>
<masterControls:ControlContent ControlContentPlaceHolderID="myContent1" runat="server">
custom content 1
</masterControls:ControlContent>
<masterControls:ControlContent ControlContentPlaceHolderID="myContent2" runat="server">
custom content 2
</masterControls:ControlContent>
在子控件背后的代码中
using MasterControls;
//you must inherit the ChildUserControl class!
public partial class Control1 : ChildUserControl
{
protected void Page_Load(object sender, EventArgs e)
{
}
public override string MasterControlVirtualPath
{
//below, type the location to the master control
//you wish to apply to this control
get { return "~/MasterControl1.ascx"; }
}
}
答案 1 :(得分:2)
我能为你所寻找的东西提出的最接近的建议是templated custom control。不幸的是,如果这些东西是自定义控件而没有ascx文件,那么跨项目共享控件要容易得多。
答案 2 :(得分:1)
我设法使用以下代码使其工作:
public class MasterLoader : UserControl
{
MasterUserControl _masterUserControl;
protected override void CreateChildControls()
{
Controls.Clear();
base.CreateChildControls();
Controls.Add(MasterControl);
}
protected override void AddedControl(Control control, int index)
{
if (control is MasterUserControl)
base.AddedControl(control, index);
else
MasterControl.ContentArea.Controls.Add(control);
}
private MasterUserControl MasterControl
{
get
{
if (_masterUserControl== null)
_masterUserControl= (MasterUserControl)LoadControl("~/MasterUserControl.ascx");
return _masterUserControl;
}
}
}
子用户控件继承自MasterLoader类。主用户控件包括一个占位符控件,我将其公开为名为ContentArea的公共属性。
public partial class MasterUserControl: UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
}
public PlaceHolder ContentArea
{
get
{
return phContent;
}
}
}
事件绑定和视图状态按预期工作,而不对任何用户控件进行任何更改。
答案 3 :(得分:0)
继承。您将基本控件构建为基类,然后从中继承。
答案 4 :(得分:0)
您还可以将嵌套用户控件放在“主”用户控件中的占位符控件上。 使用接受ascx文件的虚拟路径的Load方法来加载适当的控件。