locked
Writing Templated Property in Control Designer RRS feed

  • Question

  • User1434752625 posted

    Hi, 

    I have an abstract custom control (TestControl) that exposes a Templated property (ItemTemplate). Each concrete descendant of this control will be associated with another custom control that implements ITemplate (TestTemplate) which it will use as a default template.

    At design time, I need users to be able to convert the default template to markup and customize it as needed if necessary. Can somebody please show me how I can have the designer 'write' the markup for the control's template in the designer. I want this t work something like the LoginControl's 'convert to template' task.

     Thanks

    Here's the code. The particular area of concern is the 'ConvertToTemplate' method in the TestDesigner class (lines 240-247).

        1 using System;
        2 using System.ComponentModel;
        3 using System.ComponentModel.Design;
        4 using System.Data;
        5 using System.Configuration;
        6 using System.Diagnostics;
        7 using System.IO;
        8 using System.Linq;
        9 using System.Security.Permissions;
       10 using System.Text;
       11 using System.Web;
       12 using System.Web.Security;
       13 using System.Web.UI;
       14 using System.Web.UI.Design;
       15 using System.Web.UI.Design.WebControls;
       16 using System.Web.UI.HtmlControls;
       17 using System.Web.UI.WebControls;
       18 using System.Web.UI.WebControls.WebParts;
       19 using System.Xml.Linq;
       20 
       21 namespace TemplatedControlTest
       22 {
       23     [DesignerAttribute(typeof (TestDesigner))]
       24     [ToolboxData("<{0}:TestControl runat=\"server\"></{0}:TestControl>")]
       25     public abstract class TestControl<T> : CompositeControl where T : TestTemplate, new()
       26     {
       27         protected override HtmlTextWriterTag TagKey
       28         {
       29             get
       30             {
       31                 return HtmlTextWriterTag.Div;
       32             }
       33         }
       34 
       35         private ITemplate _template;
       36         [PersistenceMode(PersistenceMode.InnerProperty)]
       37         [TemplateContainer(typeof(TestContainer))]
       38         [Browsable(false)]
       39         public ITemplate ItemTemplate
       40         {
       41             get { return _template; }
       42             set { _template = value; }
       43         }
       44 
       45         internal bool IsDefaultTemplate
       46         {
       47             get { return this.ItemTemplate == null || this.ItemTemplate is TestTemplate ; }
       48         }
       49 
       50         [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
       51         protected override void OnDataBinding(EventArgs e)
       52         {
       53             EnsureChildControls();
       54             base.OnDataBinding(e);
       55         }
       56 
       57         private TestContainer _container;
       58         protected override void CreateChildControls()
       59         {
       60             this._container = new TestContainer(this as TestControl<TestTemplate>);
       61             if(this.ItemTemplate == null)
       62                 this.ItemTemplate = new T();
       63 
       64             this.ItemTemplate.InstantiateIn(this._container);
       65 
       66             this.Controls.Add(this._container);
       67         }
       68 
       69         public TestControl()
       70         {
       71             this.Width = new Unit(100, UnitType.Pixel);
       72             this.Height= new Unit(100, UnitType.Pixel);
       73         }
       74     }
       75 
       76     [PermissionSet(SecurityAction.InheritanceDemand, Name = "FullTrust")]
       77     [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
       78     public class TestDesigner : CompositeControlDesigner
       79     {
       80         #region Nested Types
       81 
       82         private class TestActionList : DesignerActionList
       83         {
       84             private readonly TestDesigner _parentDesigner;
       85             protected TestDesigner Parent
       86             {
       87                 get { return this._parentDesigner; }
       88             }
       89 
       90             private TestControl<TestTemplate> _parentControl;
       91             protected TestControl<TestTemplate> ParentControl
       92             {
       93                 get
       94                 {
       95                     if (this._parentControl == null)
       96                         this._parentControl = (TestControl<TestTemplate>)this.Parent.Component;
       97 
       98                     return this._parentControl;
       99                 }
      100             }
      101 
      102             public TestActionList(TestDesigner parentDesigner) : base(parentDesigner.Component)
      103             {
      104                 this._parentDesigner = parentDesigner;
      105             }
      106 
      107             public override DesignerActionItemCollection GetSortedActionItems()
      108             {
      109                 DesignerActionItemCollection items = new DesignerActionItemCollection();
      110 
      111                 string memberName, displayName, description, category = "Templates";
      112                 bool controlHasTemplate = !this.ParentControl.IsDefaultTemplate;
      113 
      114                 if(controlHasTemplate)
      115                 {
      116                     memberName = "EditTemplate";
      117                     displayName = "Edit Template";
      118                     description = "Edit the template for this control";
      119                 }
      120                 else
      121                 {
      122                     memberName = "ConvertToTemplate";
      123                     displayName = "Convert to template";
      124                     description = "Converts the control into a template that can be edited in the designer";
      125                 }
      126 
      127                 items.Add(new DesignerActionMethodItem(this, memberName, displayName, category,description, false));
      128                 return items;
      129             }
      130 
      131             public void ConvertToTemplate()
      132             {
      133                 this.Parent.ConvertToTemplate();
      134             }
      135 
      136             public void EditTemplate()
      137             {
      138                 this.Parent.EditTemplate();
      139             }
      140 
      141         }
      142 
      143         #endregion
      144 
      145         public override bool AllowResize
      146         {
      147             get{return true;}
      148         }
      149 
      150         public override void Initialize(IComponent component)
      151         {
      152             base.Initialize(component);
      153             _targetControl = (TestControl<TestTemplate>)component;
      154         }
      155 
      156         public override DesignerActionListCollection ActionLists
      157         {
      158             get
      159             {
      160                 DesignerActionListCollection actionLists =
      161                   new DesignerActionListCollection();
      162                 actionLists.AddRange(base.ActionLists);
      163                 actionLists.Add(new TestActionList(this));
      164                 return actionLists;
      165             }
      166         }
      167 
      168         private TestControl<TestTemplate> _targetControl;
      169         protected TestControl<TestTemplate> TargetControl
      170         {
      171             get{return _targetControl;}
      172         }
      173 
      174         private EditableDesignerRegion _targetRegion;
      175         protected EditableDesignerRegion TargetRegion
      176         {
      177             get { return _targetRegion; }
      178         }
      179 
      180 
      181 
      182 
      183 
      184 
      185         // Use the base to create child controls, then add region markers
      186         protected override void CreateChildControls()
      187         {
      188         }
      189 
      190         // Create the regions and design-time markup. Called by the designer host.
      191         public override String GetDesignTimeHtml(DesignerRegionCollection regions)
      192         {
      193 
      194             // Create an editable region and add it to the regions
      195             EditableDesignerRegion editableRegion = new EditableDesignerRegion(this, "Content", false);
      196             regions.Add(editableRegion);
      197 
      198             // Use the base class to render the markup
      199             return base.GetDesignTimeHtml();
      200         }
      201 
      202         // Get the content string for the selected region. Called by the designer host?
      203         public override string GetEditableDesignerRegionContent(EditableDesignerRegion region)
      204         {
      205             // Get a reference to the designer host
      206             IDesignerHost host = (IDesignerHost)Component.Site.GetService(typeof(IDesignerHost));
      207             if (host != null)
      208             {
      209                 ITemplate template = this.TargetControl.ItemTemplate;
      210 
      211                 // Persist the template in the design host
      212                 if (template != null)
      213                     return ControlPersister.PersistTemplate(template, host);
      214             }
      215 
      216             return String.Empty;
      217         }
      218 
      219         // Create a template from the content string and
      220         // put it in the selected view.
      221           public override void SetEditableDesignerRegionContent(EditableDesignerRegion region, string content)
      222           {
      223             if (content == null)
      224                 return;
      225 
      226             // Get a reference to the designer host
      227             IDesignerHost host = (IDesignerHost) Component.Site.GetService(typeof (IDesignerHost));
      228             if (host != null)
      229             {
      230                 // Create a template from the content string
      231                 ITemplate template = ControlParser.ParseTemplate(host, content);
      232 
      233                 if (template != null)
      234                 {
      235                     this.TargetControl.ItemTemplate = template;
      236                 }
      237             }
      238           }
      239 
      240         public void ConvertToTemplate()
      241         {
      242             IDesignerHost host = (IDesignerHost)Component.Site.GetService(typeof(IDesignerHost));
      243             Control template = (Control) this.TargetControl.ItemTemplate;
      244 
      245             if (host != null && template != null)
      246                 RootDesigner.AddControlToDocument(template, this.TargetControl, ControlLocation.First);
      247         }
      248 
      249         public void EditTemplate()
      250         {
      251             //show edit design surface
      252         }
      253     }
      254 
      255     public class TestContainer : WebControl, INamingContainer
      256     {
      257         private readonly TestControl<TestTemplate> _parent;
      258         public TestContainer(TestControl<TestTemplate> parent)
      259         {
      260             this._parent = parent;
      261         }
      262 
      263         public TestControl<TestTemplate> Container
      264         {
      265             get { return this._parent; }
      266         }
      267     }
      268 
      269 
      270     public class TestTemplate : WebControl, ITemplate
      271     {
      272         public void InstantiateIn(Control container)
      273         {
      274             container.Controls.Add(this);
      275         }
      276 
      277         public TestTemplate()
      278         {
      279             Label lbl = new Label();
      280             lbl.Text = "This is a programmatically created template";
      281             this.Controls.Add(lbl);
      282         }
      283     }
      284 
      285     public class TestControl2 : TestControl<TestTemplate>
      286     {
      287     }
      288 }
    
    Tuesday, March 25, 2008 5:51 AM

All replies