创建自定义面板控件

时间:2010-10-01 11:47:41

标签: c# asp.net user-controls panel

基于服务器的控件对我来说不是一个好的解决方案,因为我的面板默认情况下应该总是包含一个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)抛出异常。

3 个答案:

答案 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);
 }