Loading a Template From a User Control

What if you wanted to load a template (ITemplate property) from an external user control (.ascx) file?

Yes, it is possible; there are a number of ways to do this, the one I'll talk about here is through a type converter.

You need to apply a TypeConverterAttribute to your ITemplate property where you specify a custom type converter that does the job. This type converter relies on InstanceDescriptor. Here is the code for it:

	public class TemplateTypeConverter: TypeConverter
	{
		public override Boolean CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
		{
			return ((sourceType == typeof(String)) || (base.CanConvertFrom(context, sourceType) == true));
		}

		public override Boolean CanConvertTo(ITypeDescriptorContext context, Type destinationType)
		{
			return ((destinationType == typeof(InstanceDescriptor)) || (base.CanConvertTo(context, destinationType) == true));
		}

		public override Object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, Object value, Type destinationType)
		{
			if (destinationType == typeof(InstanceDescriptor))
			{
				Object objectFactory = value.GetType().GetField("_objectFactory", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(value);
				Object builtType = objectFactory.GetType().BaseType.GetField("_builtType", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(objectFactory);				
				MethodInfo loadTemplate = typeof(TemplateTypeConverter).GetMethod("LoadTemplate");				
				return (new InstanceDescriptor(loadTemplate, new Object [] { "~/" + (builtType as Type).Name.Replace('_', '/').Replace("/ascx", ".ascx") }));
			}
			
			return base.ConvertTo(context, culture, value, destinationType);
		}

		public static ITemplate LoadTemplate(String virtualPath)
		{
			using (Page page = new Page())
			{
				return (page.LoadTemplate(virtualPath));
			}
		}
	}

And, on your control:

public class MyControl: Control
{
	[Browsable(false)]
	[TypeConverter(typeof(TemplateTypeConverter))]
	public ITemplate Template
	{
		get;
		set;
	}
}

This allows the following declaration:

	

Hope this helps!

Bookmark and Share

                             

No Comments

Add a Comment

As it will appear on the website

Not displayed

Your website