ASP.Net容器控制设计器

时间:2010-11-19 16:37:21

标签: asp.net custom-controls containers designer design-time

我给...在几天试图弄清楚我错过了什么后我放弃了。我无法弄清楚如何让我的简单容器控件在设计器中正确显示。以下是自定义控件的基本标记:

<div>
    <div>Title</div>
    <div>
        <!-- ASP.Net child controls -->
    </div>
</div>

以下是它在运行时的看法(标题,然后子控件是GridView):

alt text

以下是基本容器控件的简单代码:

namespace Shoe.Controls
{
    //[Designer(typeof(ApplicationWindowDesigner))]
    //[ParseChildren(false)]
    //[PersistChildren(true)]
    [ToolboxData("<{0}:ApplicationWindow runat=\"server\"></{0}:ApplicationWindow>")]
    public class ApplicationWindow : System.Web.UI.WebControls.Panel
    {
        #region Designer Properties
        [Category("Appearance")]
        [DefaultValue("Application")]
        [Description("Title that will appear at the top of the Window.")]
        [Browsable(true)]
        /*
        public string Title
        {
            get{return (ViewState["ApplicationWindowTitle"] == null)? 
                string.Empty : 
                (string)ViewState["ApplicationWindowTitle"];}

            set{ViewState["ApplicationWindowTitle"] = value;}
        }
        */
        public string Title {get; set;}

        #endregion
        #region Rending Methods

        /*
        protected override void Render(HtmlTextWriter writer)
        {
            this.EnsureChildControls();

            writer.Write("<div class=\""+CssClass+"\" style=\"width: "+Width+"; height: "+Height+";\"><div>"+Title+"</div><div>");
            RenderChildren(writer);
            writer.Write("</div></div>");
        }
        */

        public override void RenderBeginTag(HtmlTextWriter writer)
        {
            writer.Write("<div class=\""+CssClass+"\" style=\"width: "+Width+"; height: "+Height+";\"><div>"+Title+"</div><div>");
            //base.RenderBeginTag(writer);
        }

        public override void RenderEndTag(HtmlTextWriter writer)
        {
            //base.RenderEndTag(writer);
            writer.Write("</div></div>");
        }
        #endregion
    }
}

如上所示,它目前基于Panel控件。但是,我也尝试过使用WebControl作为基类,然后提供我自己的设计器,如下所示:

namespace Shoe.Controls
{
    public class ApplicationWindowDesigner : ContainerControlDesigner
    //public class ApplicationWindowDesigner : ControlDesigner
    {
        /*
        public override void Initialize(IComponent component)
        {
            base.Initialize(component);

            SetViewFlags(ViewFlags.DesignTimeHtmlRequiresLoadComplete, true);
        }

        public override string GetDesignTimeHtml()
        {
            //return base.GetDesignTimeHtml();

            StringBuilder   sb  = new StringBuilder();
            TextWriter      s   = new StringWriter(sb);
            HtmlTextWriter  h   = new HtmlTextWriter(s);

            ApplicationWindow app_wnd = (ApplicationWindow)this.Component;

            app_wnd.RenderControl(h);

            h.Dispose();
            s.Dispose();

            return sb.ToString();
        }
        */
        /*
        public override string GetDesignTimeHtml(DesignerRegionCollection regions)
        {
            //return base.GetDesignTimeHtml(regions);
            ApplicationWindow app_wnd = (ApplicationWindow)this.Component;

            /
            return GetDesignTimeHtml();
        }
        */
    }
}

如您所见,我尝试使用ControlDesigner作为基类,使用ContainerControlDesigner作为基类。当我使用ControlDesigner时,我让设计师正确渲染我的标题栏和div;但是它不呈现子控件(GridView)。如果我使用ContainerControlDesigner,它将呈现子控件,但不会呈现标题栏和div。我无法弄清楚这个神奇的组合会给我一个设计师渲染周围的框架和儿童控件。

以下是使用Panel作为控件的基类,没有设计器以及Begin / End标记方法时设计器中的样子:

alt text

当我使用WebControl作为控件的基类并使用基于ContainerControlDesigner的设计器(子控件,但我的标题栏和div缺失)时,这也是它的样子。

我错过了什么?我已经找到了几个ContainerControlDesigner的例子,但是没有一个像我一样向周围的控件添加任何东西。

1 个答案:

答案 0 :(得分:2)

你在正确的轨道上...我做了类似的事情来制作圆形面板。只需放入面板并让渲染创建周围的div就可以变得非常容易。我可以放下子控件并正确渲染它们。只需包装基础渲染方法。

Web控制(工作示例)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.Design.WebControls;
using System.ComponentModel;
using System.ComponentModel.Design;

namespace MyExample
{
    [DefaultProperty("Text")]
    [ToolboxData("<{0}:myPanel runat=server></{0}:bPanel>")]
    [Designer(typeof(MyPanelDesigner))]
    public class MyPanel : Panel
    {
        #region Property


        private string _Title = "No Title Set";
        public string Title
        {
            get { return _Title; }
            set { _Title = value; }
        }

        #endregion

        protected override void RenderChildren(HtmlTextWriter writer)
        {

            writer.Write(String.Format("<div><div>{0}</div></div>", this.Title));
            base.RenderChildren(writer);
            writer.Write("</div></div>");
        }

    }


    public class MyPanelDesigner : PanelContainerDesigner
    {
        public override string GetDesignTimeHtml(System.Web.UI.Design.DesignerRegionCollection regions)
        {
            // Read Property off control
            MyPanel c = (MyPanel)Component;
            string sTitle = c.Title;

            // Render design markup
            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("<div><div>{0}</div></div>", sTitle);
            sb.Append(base.GetDesignTimeHtml(regions));
            sb.AppendFormat("</div></div>");
            return sb.ToString();
        }
    }

}