基于服务器的控件对我来说不是一个好的解决方案,因为我的面板默认情况下应该总是包含一个asp 复选框,它允许用户隐藏和显示面板内容。
我创建了我的Panel作为模板化的用户控件,但现在我遇到了无法在其中声明变量的问题。
[ParseChildren(true)]
public partial class MyPanel: System.Web.UI.UserControl
{
private ITemplate messageTemplate = null;
[TemplateContainer(typeof(MessageContainer))]
[PersistenceMode(PersistenceMode.InnerProperty)]
public ITemplate Content
{
get
{
return messageTemplate;
}
set
{
messageTemplate = value;
}
}
void Page_Init()
{
MessageContainer container = new MessageContainer();
messageTemplate.InstantiateIn(container);
PlaceHolder1.Controls.Add(container);
}
[ParseChildren(true)]
public class MessageContainer : Control, INamingContainer
{
internal MessageContainer()
{
}
}
}
如果我在MyPage.aspx
中执行以下操作,则控件定义 插入到MyPage.aspx.designer.cs
中它们通常会执行:
<my:MyPanel>
<Content>
<asp:TextBox id = "foo" runat="server" />
</Content>
</my:MyPanel>
因此设计人员不会将foo
创建为控件变量,因此我无法访问它。
如何创建自己的Panel,允许在其中声明控件?
修改
我现在尝试使用[ParseChildren(false)]
。包含变量的变量现在在表单的设计器代码中生成。现在问题是messageTemplate.InstantiateIn(container)
抛出异常。
答案 0 :(得分:0)
您尚未为控件提供代码。通常,它需要实现INamingContainer,并且应该具有ITemplate类型的属性来接受模板。 检查MSDN如何开发一个。这是来自MSDN的sample code。另请检查此article以获取数据绑定模板控件。
答案 1 :(得分:0)
首先,您需要使用runat =“server”属性。
<asp:TextBox id = "foo" runat="server"/>
之后你可以尝试
var textbox = this.MyCustomPanel.FindControl("foo") as TextBox;
而不是使用FindControl我想通过在Usercontrol的INamingTemplate容器的设计器设置上设置属性来实现此行为
答案 2 :(得分:0)
您无需创建模板化控件,只需创建复合Web控件即可。创建一个Panel&amp;复选框,将它们添加到复合控件的控件集合中,调整渲染以根据需要显示它,然后使用它运行。
看here
*编辑**
这是您需要的工作实现。 Make为Web.dll创建一个引用。
CustomPanel.cs
using System;
using System.ComponentModel;
using System.Drawing;
using System.Security.Permissions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace Web
{
[ AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal),
AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal),
ToolboxData("<{0}:CustomPanel runat=\"server\"> </{0}:CustomPanel>"),
]
public class CustomPanel : CompositeControl
{
private Panel panelContainer;
private CheckBox chkHideContent;
private Panel panelInnerContainer;
[Bindable(true),
Category("Appearance"),
DefaultValue(""),
Description("The text to display with the checkbox.")]
public string CheckBoxText
{
get
{
EnsureChildControls();
return chkHideContent.Text;
}
set
{
EnsureChildControls();
chkHideContent.Text = value;
}
}
[Bindable(true)]
[Category("Data")]
[DefaultValue("")]
[Localizable(true)]
public bool IsCheckBoxChecked
{
get
{
return chkHideContent.Checked;
}
}
[Bindable(true)]
[Category("Data")]
[DefaultValue("")]
[Localizable(true)]
public bool HideInnerPanel
{
set
{
EnsureChildControls();
panelInnerContainer.Visible = value;
}
}
[Bindable(true)]
[Category("Data")]
[DefaultValue("")]
[Localizable(true)]
public ControlCollection InnerPanelControls
{
get
{
EnsureChildControls();
return panelInnerContainer.Controls;
}
}
protected virtual void OnCheckboxChanged(EventArgs e)
{
if (chkHideContent.Checked)
{
panelInnerContainer.Visible = false;
}
else
{
panelInnerContainer.Visible = true;
}
}
private void _checkbox_checkChanged(object sender, EventArgs e)
{
OnCheckboxChanged(EventArgs.Empty);
}
protected override void RecreateChildControls()
{
EnsureChildControls();
}
protected override void CreateChildControls()
{
Controls.Clear();
panelContainer = new Panel();
panelContainer.ID = "panelContainer";
chkHideContent = new CheckBox();
chkHideContent.ID = "chkHideContent";
chkHideContent.CheckedChanged += new EventHandler(_checkbox_checkChanged);
chkHideContent.AutoPostBack = true;
panelInnerContainer = new Panel();
panelInnerContainer.ID = "panelInnerContainer";
this.Controls.Add(panelContainer);
this.Controls.Add(chkHideContent);
this.Controls.Add(panelInnerContainer);
}
protected override void Render(HtmlTextWriter writer)
{
panelContainer.RenderBeginTag(writer);
chkHideContent.RenderControl(writer);
panelInnerContainer.RenderControl(writer);
panelContainer.RenderEndTag(writer);
}
}
}
Default.aspx的
<%@ Register assembly="Web" namespace="Web" tagprefix="cc1" %>
<cc1:CustomPanel ID="CustomPanel1" runat="server" />
Default.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
Label lbl = new Label();
lbl.Text = "IT WORKS!";
CustomPanel1.CheckBoxText = "Hide my innards!";
CustomPanel1.InnerPanelControls.Add(lbl);
}