views:

583

answers:

2

Hi Guys

Im looking to create a custom ASP.NET container control that will allow me to drag further controls into it within the VS designer.

The final HTML that im looking for is very simple..

<div id="panel1">
    <div id="panel2">
    </div>
    <div id="panel2">
    </div>
</div>

With additional controls being able to be dragged into panels 2 and 3.

Im sure its very simple but im struggling to find examples that will help.

Any pointers or ideas are appreciated!

Cheers Stuart

A: 

Here is a link to a MSDN article regarding what you are trying to do, unfortunently there is no VS designer support so it renders correctly from the server but not in the IDE.

How to: Create Templated ASP.NET User Controls
http://msdn.microsoft.com/en-us/library/36574bf6.aspx

Christopher Kelly
A: 

I've done such things in the past, and yes, from my experience at that time there is not much documentation available. Even worse, at that time some of the documentation was incorrect or vague!

So, to save you all the headaches (ouch, it already starts to hurt when I just think of it :-P), here is some information you definitely need to know.

Basically all controls are for run-time use only. You can attach a ControlDesigner to a control with an attribute on the class definition, which the design time environment (VS.NET IDE) will load and use as a layer on top of your control.

Templates

Chris' suggestion to use Templates is in the right direction. Your control needs to store somewhere the 'content' of the div's, and Templates are the perfect solution. Make sure you get this part right at first. Note: template properties can behave weird if they have a set clause! Moreover, check the use of NotifyParentAttribute also.

When you've got the templates in place, and you can use declarative syntax in ASPX pages to add controls, and they render well, then you can start working on the designer.

For the designer you have 2 options; the easy and complex way.

Easy designer solution

Let's start with the easy way. The base ControlDesigner classes already provide a framework to show templates. You have probably already seen this in action, like in the GridView control and its template fields.

Check out the following MSDN article on creating a template control designer.

With this easy solution, you get an automatic implementation of the smart tag (the arrow to the right of a control during design-time), and can select a template to edit from a drop down list.

Complex designer solution

Now, if this is not really satisfying for you, and you would like to be able to edit controls just like a Panel control, then you have to dig deeper. So here is the complex solution using Control Designer Regions.

See the example in the example in the EditableDesignerRegion class.

What this example does, is overriding the CreateChildControls of the designer class. Remember I said the designer control is a layer on top of your run-time control? So this CreateChildControls method will run after your control's implementation. What you have to do, is mark a HTML element within your render output with a special designer region HTML attribute. In this way, the designer knows what part in your rendered control should be a region.

Now you have to instruct the IDE to assign a editor or viewer to your regions. You have to do this in the GetDesignTimeHtml(DesignerRegionCollection regions) method (notice the overloaded version of this method). As you can see, this method receives a collection of regions. You have to assign your editable of view regions to this collection. Important here - and this is the badly documented part - is that the order in this collection is very important. The value of the region attribute in your HTML, refers to the index in this collection.

So, now we have defined regions in our rendered output, assigned a editor or viewer to it. Next up is how to fill these regions and store the value from these regions back into our controls declaration.

These two actions are handled in GetEditableDesignerRegionContent and SetEditableDesignerRegionContent methods of the control designer. Here you see why it's important to name the regions that you've added to the collection in the GetDesignTimeHtml method. In these two methods you receive the region reference and by it's Name property you could determine which Template property of your control to read/write.

To read and write the template properties we use the magic of the ControlPersister and ControlParser. The persister creates an template instance from declarative ASP.NET (HTML) code. The parser does the job the other way around; creates plain HTML from a template instance.

In a nutshell

So it's up to you to decide whether the standard template editing framework is good enough for you. If you want to have fancy edit capabilities for both of your edit regions in your IDE, then you will have to implement the complex solution. Otherwise just stick with the simple implementation. The examples mentioned will help you a lot.

bgever