1

私はあきらめます... 私が欠けているものを理解しようと何日も試みた後、私はあきらめます。シンプルなコンテナー コントロールをデザイナーに正しく表示する方法がわかりません。カスタム コントロールの基本的なマークアップは次のとおりです。

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

実行時の外観は次のとおりです (タイトルと子コントロールは GridView です)。

代替テキスト

基本的なコンテナ コントロールの簡単なコードを次に示します。

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 タグ アプローチを使用する場合、デザイナーでどのように表示されるかを次に示します。

代替テキスト

これは、コントロールの基本クラスとして WebControl を使用し、ContainerControlDesigner に基づいたデザイナーを使用した場合にも表示されます (子コントロールですが、タイトル バーと div がありません)。

私は何が欠けていますか?ContainerControlDesigner の例をいくつか見つけましたが、私のように周囲のコントロールに実際に何かを追加するものはありません。

4

1 に答える 1

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();
        }
    }

}
于 2010-11-19T20:27:11.077 に答える