Jaa


TFS 2010 - Using a TypeConverter to display your custom Process Parameter list type

I just helped someone today with this common problem...

"How do I get my custom list process parameter to show something besides '(Collection)' in the Process Parameter property grid?"

The answer is really simple if you are familiar with the WinForms property grid. The PropertyGrid class looks for type converter attributes on the classes to determine how to display them. For a simple class (not convertable to String), if you don't do anything, it will simply call ToString() to display the text and the text will be readonly. For a list (or really collection), it doesn't call ToString. Rather, it simply displays "(Collection)". Again this value is readOnly.

However, by adding a TypeConverter attribute to your class or list, you can tell the PropertyGrid how to display your type and even how to allow text editing within the Property Grid. Here is a simple example of a List of Strings. That has a type converter that allows the user to type in the list and see the list without needing a custom editor.

Note: This class is just a simple example. For instance, it does not handle strings that have embedded commas.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;

namespace MyCustomProcessParameters
{
    [Serializable]
    [TypeConverter(typeof(ListOfStringsTypeConverter))]
    public class ListOfStrings : List<String>
    {
        public ListOfStrings()
            : base()
        {
        }

        public ListOfStrings(String list)
            : base()
        {
            AddRange(list.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries));
        }

        public override string ToString()
        {
            return String.Join(",", this);
        }
    }

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

        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            return ((destinationType == typeof(String)) || base.CanConvertTo(context, destinationType));
        }

        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            if (!(value is String))
            {
                return base.ConvertFrom(context, culture, value);
            }

            return new ListOfStrings((String)value);
        }

        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
            if (destinationType != typeof(String) || !(value is ListOfStrings))
            {
                return base.ConvertTo(context, culture, value, destinationType);
            }

            return value.ToString();
        }
    }

}

Here is what it looks like in a test app that has a PropertyGrid:

 In the picture above, you can see that I added three read only properties to my object that allow me to see the individual items in the list.

Note that for TypeConverters to work with your process parameter types, you may need SP1 of TFS 2010 and you may have to make sure your assemblies are in the probing path for Visual Studio.

Happy coding!

Comments

  • Anonymous
    January 12, 2012
    Nice! Will having them in the custom assemblies version control path for the build controller satisfy the local probing path requirement since Team Explorer will download custom assemblies from there as well?

  • Anonymous
    January 12, 2012
    Unfortunately, that isn't enough. We recently fixed a bug that makes this work without you having to do anything, but that fix won't make it out until we ship the next version :(

  • Anonymous
    January 18, 2012
    The comment has been removed

  • Anonymous
    January 18, 2012
    Hi Sylvain, Try the Required property in the Metadata for the process parameter. See blogs.msdn.com/.../tfs-2010-custom-process-parameters-part-2-metadata.aspx for more information. Thanks, Jason

  • Anonymous
    February 06, 2012
    Thanks Jason, you helped me a lot. :-)