ProfK
ProfK

Reputation: 51063

How do I implement a System.Type property in markup for a User Control?

This is a follow up to another question of mine where I first found this problem. If I create a public property on my User Control, with a type of System.Type, I cannot use a normal string representation of the type, e.g. System.Int32, as a declarative markup attribute value for the property.

It seems I need to uncover whatever it is that does the conversion from string to type, and 'inject' a custom one for System.Type. Am I on the right track?

Upvotes: 1

Views: 318

Answers (2)

Ruslan
Ruslan

Reputation: 1761

You need a TypeConverter. Most of primitive types have default ones. They are used by ControlBuilders. .NET may already have something for the System.Type, but I don't know of any. So, here is how you could add your own:

On page:

<uc1:WebUserControl1 ID="WebUserControl11" runat="server" MyProperty="System.Int32" />

User control code behind:

using System.ComponentModel;

public partial class WebUserControl1 : System.Web.UI.UserControl
{
    [TypeConverter(typeof(MyTypeConverter))]
    public System.Type MyProperty { get; set; }

    protected void Page_Load(object sender, EventArgs e)
    {
        //dummy user web control, simply outputs property's value
        Response.Write(MyProperty.ToString());
    }
}

public class MyTypeConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return ((sourceType == typeof(string)) || base.CanConvertFrom(context, sourceType));
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        if (value is string)
        {
            string str = ((string)value).Trim();
            try
            {
                return Type.GetType(str);
            }
            catch (FormatException exception)
            {
                throw new FormatException(string.Format("ConvertInvalidPrimitive={0} is not a valid value for {1}.", value, "System.Type"), exception);
            }
        }
        return base.ConvertFrom(context, culture, value);
    }

    public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
    {
        return false;
    }
}

Upvotes: 4

JP Alioto
JP Alioto

Reputation: 45117

How about just using the type instead of using the string representation? You can get the compile-time type with typeof and you can get the run-time type with Object.GetType(). Either one returns a System.Type.

Upvotes: 1

Related Questions