Mann Software
Mann Software > SharePoint and the Office System > Posts > User Controls NOT in the ControlTemplates folder
User Controls NOT in the ControlTemplates folder

A recommendation you'll see floating about the web is to put any custom user controls you create into the CONTROLTEMPLATES directory. However, it's like placing files into LAYOUTS – it's better to be in your own sub-folder. For RenderingTemplates though SharePoint apparently looks for them ONLY in the CONTROLTEMPLATES folder. So how can we get them into a subfolder?

Basically, you just need to put them there (as part of your Solution deployment, of course).

The web.config file for SharePoint contains a line that registers anything in or under the CONTROLTEMPLATES folder as "safe":

<SafeControl Src="~/_controltemplates/*" IncludeSubFolders="True" Safe="True" AllowRemoteDesigner="True" />

So we don't need a new SafeControl entry. You will get an error in your ULS logs:

Control template "MyFieldControl" does not exist.

But you can safely ignore this…

One other problem you'll have if you're doing this in a custom field (and perhaps other locations – I haven't tested) is verifying that your custom UI controls exist. Since SharePoint "can't find" your template, you'll have a problem. Most sample custom fields you'll find floating around the web contain code something like this in the CreateChildControls method of the control display page:

ddlLookup = (DropDownList)(TemplateContainer.FindControl("ddlLookup"));

if (ddlLookup == null)

{

throw new ArgumentException("ddlLookup is null. Corrupted

    LookupControl.ascx file.");

}

All you need to do is explicitly load the field's user control, load the TemplateContainer control (which is your RenderingTemplate) and then search recursively for your UI control by ID:

TemplateContainer templateContainer = new TemplateContainer();

Control ctl = (Control)Page.LoadControl

    ("~/_controltemplates/MyField/ MyField_UserDisplay.ascx");

templateContainer.Template = ((RenderingTemplate)ctl.Controls[0]).Template;

Controls.Add(templateContainer);

 

ddlLookup = (DropDownList)FindChildControlRecursive(this, "ddlLookup");

if (this.phDynamicControls == null)

{

throw new ArgumentException("ddlLookup is null. Corrupted

    LookupControl.ascx file.);

}

Note: the FindChildControlRecursive method simply iterates through the control hierarchy starting at the specified control (first parameter – this) looking for a control with the ID specified in the second parameter (ddlLookup).

 

Comments

DJ

You deploy custom pages for content types via the controltemplates folder as well, and putting them in a subfolder will mean SharePoint won't find them when it goes to render your display\edit\new page via your custom control. This seems to at least be one place where a separate subfolder is self-defeating. We use prefixing, i.e., MyCompany_UserControl.ascx instead of a separate folder.
System Account at 8/14/2009 4:38 PM
SharePoint Server MVP Community Kit for SharePoint Philly Office Geeks ISPA