Monday, January 22, 2007

Lindsay Dawn Mackenxie 16 Daily Sport

Templated Control with Designer Support

For my current project we needed a nicely formatted box that has a title. Place them on each side of x-times to build with table tags and format, we wanted to use your own control.

first Experiment: Create a simple control derived from the class controls satisfy our needs only moderate, since it could be used between the start and end tag, text only. But we wanted to ASP.NET Controls placed in the box.

[default property ("Title") ToolboxData(" <{0}:SimpleBox runat=server> ")]
public class SimpleBox : Control
{
private string _title;

[Bindable(true), Category("Appearance"), DefaultValue("")]
public string Title
{
get { return _title; }
set { _title = value; }
}

protected override void Render(HtmlTextWriter output)
{
string outputString = string.Empty;

// generate output (html)
outputString = "&#060;table cellspacing="0" cellpadding="0" border="1"&#062;"
+ " &#060;tr&#062;"
+ " &#060;td&#062;" + Title + "&#060;/td&#062;"
+ " &#060;/tr&#062;"
+ " &#060;tr&#062;"
+ " &#060;td&#062;";

// read between the begin and end tag
if ((HasControls()) &&amp; (Controls[0] is LiteralControl))
{
outputString += ((LiteralControl)Controls[0]).Text;
}

string outputStringEnd = "&#060;/td&#062;"
+ " &#060;/tr&#062;"
+ "&#060;/table&#062;";

// speak your mind
output.Write(outputString);
}}



second Experiment: Creating a Composite Controls
That was better. The controls between the start and end tags are detected and rendered. The only problem was the events of the Child Controls. These were not fired. Could you writing out programs, but ...

[default property ("Title"), ToolboxData (<{0}:ComposedBox runat=server> ")]
public class ComposedBox: Control, INamingContainer
{
private string _title;

/ (true) / [Bindable, Category (" Appearance "), DefaultValue _title get return
("")] public string Title {


{
;

} {set

_title = value;}

}

PROTECTED Override void CreateChildControls () {

outputStringStart string = "\u0026lt;table cellspacing="0" cellpadding="0" border="1">"
+ "\u0026lt;tr & # 062;
+ "\u0026lt;td>" + Title + "\u0026lt;/ td>"
+ "\u0026lt;/ tr>"
+ "\u0026lt; tr> "
+" \u0026lt;td> "

outputStringEnd string =" \u0026lt;/ td> "
+" \u0026lt;/ tr> "
+" \u0026lt;/ table>
";

this.Controls.AddAt (0, (new LiteralControl (output string start)));
this.Controls.AddAt (this.Controls.Count - 1, (new LiteralControl (outputStringEnd)));}

}


Experiment 3: The Templated Control
does this all at once, without much programming effort in a short time was our control and creates the formatted box was available in a revised version, we integrated then also the lack of designer support... ! Great


public class BoxTemplate: composite control, INamingContainer

{private String _message = null;
public BoxTemplate () {} public
BoxTemplate (String message)
{
_message = message;
}
public String Message
{
get { return _message; }
set { _message = value; }
}
}

[DefaultProperty("Title"),
ParseChildren(true), PersistChildren(false),
Designer("CSBS.TVCITTool.Client.Web.Controls.TemplatedBoxControlDesigner, CSBS.TVCITTool.Client.Web.Controls"),
ToolboxData(" <{0}:TemplatedBox runat=server> ")]
public class TemplatedBox : CompositeControl, INamingContainer
{
private string _title;
private ITemplate _messageTemplate = null;
private String _message = null;

public String Message
{
get { return _message; }
set { _message = value; }
}

[Bindable(true), Category("Appearance"), DefaultValue("")]
public string Title
{
get { return _title; }
set { _title = value; }
}

[PersistenceMode(PersistenceMode.InnerProperty), DefaultValue(null), TemplateContainer(typeof(BoxTemplate)),
TemplateInstance(TemplateInstance.Single), Browsable(false)]
public ITemplate MessageTemplate
{
get { return _messageTemplate; }
set { _messageTemplate = value; }
}

public override void DataBind()
{
EnsureChildControls();
base.DataBind();
}

protected override void CreateChildControls()
{
// If a template has been specified, use it to create children.
// Otherwise, create a single literalcontrol with message value

string outputStringStart = "
&#060;table class="boxframe" cellspacing="'\"&#062;"
+ " &#060;tbody&#062;&#060;tr&#062;"
+ " &#060;td class="boxheader"&#062;" + Title + "&#060;/td&#062;"
+ " &#060;/tr&#062;"
+ " &#060;tr&#062;"
+ " &#060;td&#062;";

string outputStringEnd = "&#060;/td&#062;"
+ " &#060;/tr&#062;"
+ "&#060;/tbody&#062;&#060;/table&#062;
";

if (MessageTemplate != null)
{
Controls.Clear();
BoxTemplate i = new BoxTemplate(this.Message);
MessageTemplate.InstantiateIn(i);
Controls.Add(i);
}
else
{
this.Controls.Add(new LiteralControl(this.Message));
}

this.Controls.AddAt(0, (new LiteralControl(outputStringStart)));
this.Controls.AddAt(this.Controls.Count, (new LiteralControl(outputStringEnd)));
}
}

public class TemplatedBoxControlDesigner : CompositeControlDesigner
{
private TemplatedBox _designControl;
private TemplateGroupCollection _templateGroupCollection;

public override void Initialize(System.ComponentModel.IComponent component)
{
base.Initialize(component);
_designControl = (TemplatedBox)component;
SetViewFlags(ViewFlags.DesignTimeHtmlRequiresLoadComplete, true);
SetViewFlags(ViewFlags.TemplateEditing, true);
}

public override TemplateGroupCollection TemplateGroups
{
get
{
if (_templateGroupCollection == Null)
{
_templateGroupCollection = base.TemplateGroups;
TemplateGroup group;
template definition template definition;
group = new template group (ContextRowTemplates ");
template definition = new template definition (this," message template ", _designControl," message template " false) / / the fourth parameter is the name of the Property Control
group.AddTemplateDefinition (template definition is);
_templateGroupCollection.Add (group);} return

_templateGroupCollection;}

}}

0 comments:

Post a Comment