Q: Show a property editor containing list of types derived from a certain base I need your help, you will see. I have a project where I have 2 forms (WindowList and WindowMaintenance) that will inherit many others.
This is the WindowList code : The WindowMaintenanceForm property in the WindowList form will be used to select a form of the WindowMaintenance type (this will be used to create the form via reflection).

public partial class WindowList : System.Windows.Forms.Form
{
    public WindowList()
    {
        InitializeComponent();
    {

    [TypeConverter(typeof(MaintenanceFormTypeConverter))]
    public Type WindowMaintenanceForm { get; set; }
}


This is the WindowMaintenance code:

public partial class WindowMaintenance : System.Windows.Forms.Form
{
    public WindowMaintenance()
    {
        InitializeComponent();
    {
}


Now the structure of the project is as follows:

+ Solution.GUI
  Ⱶ Properties
  Ⱶ References
  Ⱶ CustomLibraries (folder)
    Ⱶ WindowList
    Ⱶ WindowMaintenance
  Ⱶ Modules (folder)
    Ⱶ User (folder)
      Ⱶ win__list (inherits from CustomLibraries.WindowList)
      Ⱶ win__maintenance_a (inherits from CustomLibraries.WindowMaintenance)
      Ⱶ win__maintenance_b (inherits from CustomLibraries.WindowMaintenance)
    Ⱶ Customer (folder)
      Ⱶ win__list (inherits from CustomLibraries.WindowList)
      Ⱶ win__maintenance (inherits from CustomLibraries.WindowMaintenance)
      Ⱶ win__maintenance_01 (inherits from CustomLibraries.WindowMaintenance)
      Ⱶ win__maintenance_02 (inherits from CustomLibraries.WindowMaintenance)
      Ⱶ win__maintenance_a (inherits from CustomLibraries.WindowMaintenance)
    Ⱶ Sales (folder)
      Ⱶ win__list (inherits from CustomLibraries.WindowList)
      Ⱶ win__maintenance (inherits from CustomLibraries.WindowMaintenance)


This is the code of MaintenanceFormTypeConverter:

public class MaintenanceFormTypeConverter : TypeConverter
{
    public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
    {
        return true;
    }

    public override bool CanConvertTo(ITypeDescriptorContext pContext, Type pDestinationType)
    {
        return base.CanConvertTo(pContext, pDestinationType);
    }

    public override object ConvertTo(ITypeDescriptorContext pContext, CultureInfo pCulture, object pValue, Type pDestinationType)
    {
        return base.ConvertTo(pContext, pCulture, pValue, pDestinationType);
    }

    public override bool CanConvertFrom(ITypeDescriptorContext pContext, Type pSourceType)
    {
        if (pSourceType == typeof(string))
            return true;

        return base.CanConvertFrom(pContext, pSourceType);
    }

    public override object ConvertFrom(ITypeDescriptorContext pContext, CultureInfo pCulture, object pValue)
    {
        if (pValue is string)
            return GetTypeFromName(pContext, (string)pValue);

        return base.ConvertFrom(pContext, pCulture, pValue);
    }

    public override bool GetStandardValuesSupported(ITypeDescriptorContext pContext)
    {
        return true;
    }

    public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext pContext)
    {
        List<Type> types = GetProjectTypes(pContext);
        List<string> values = new List<string>();

        foreach (Type type in types)
            values.Add(type.FullName);

        values.Sort();

        return new StandardValuesCollection(values);
    }

    private List<Type> GetProjectTypes(IServiceProvider serviceProvider)
    {
        var typeDiscoverySvc = (ITypeDiscoveryService)serviceProvider.GetService(typeof(ITypeDiscoveryService));
        var types = typeDiscoverySvc.GetTypes(typeof(object), true).Cast<Type>().Where(item => item.IsPublic && typeof(Form).IsAssignableFrom(item) && !item.FullName.StartsWith("System")).ToList();

        return types;
    }

    private Type GetTypeFromName(IServiceProvider serviceProvider, string typeName)
    {
        ITypeResolutionService typeResolutionSvc = (ITypeResolutionService)serviceProvider.GetService(typeof(ITypeResolutionService));

        return typeResolutionSvc.GetType(typeName);
    }
}


Here I have the problem, the WindowMaintenanceForm property in all the forms inherited from WindowList shows all the forms of the project, however I only need to show those that inherit from WindowMaintenance and are only within the same folder.
For example, the WindowMaintenanceForm property in the Modules.Customer.win__list form should only list the Modules.Customer.win__maintenance, Modules.Customer.win__maintenance_01, Modules.Customer.win__maintenance_02 and Modules.Customer.win__maintenance_a forms (and so on respectively for each case).
I would appreciate any help you can give me. Thanks and regards.

A: Well, it's not about the folder, it's about forms which are derived from a certain form. I've improved my FormTypeConverter and created a generic version of it. So you can easily define something like this:
[TypeConverter(typeof(TypeTypeConverter<BaseForm>))]
public Type FormType { get; set; }

Then it shows a dropdown containing BaseForm and all it's derived Forms, ignoring the abstract classes:

Generic TypeTypeConverter - A property editor to allow choosing a type which are derived from a certain base
And here is the code for the generic TypeTypeConverter:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Globalization;
using System.Linq;
public class TypeTypeConverter<T> : TypeConverter
{
    public override bool GetStandardValuesExclusive
          (ITypeDescriptorContext context)
    {
        return true;
    }
    public override bool CanConvertFrom(ITypeDescriptorContext context,
        Type sourceType)
    {
        if (sourceType == typeof(string))
            return true;
        return base.CanConvertFrom(context, sourceType);
    }
    public override object ConvertFrom
        (ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        if (value is string)
            return GetTypeFromName(context, (string)value);
        return base.ConvertFrom(context, culture, value);
    }

    public override bool GetStandardValuesSupported
        (ITypeDescriptorContext context)
    {
        return true;
    }
    public override StandardValuesCollection GetStandardValues
        (ITypeDescriptorContext context)
    {
        return new StandardValuesCollection(GetProjectTypes(context)
            .OrderBy(x => x.FullName).ToList());
    }
    private List<Type> GetProjectTypes(IServiceProvider serviceProvider)
    {
        var typeDiscoverySvc = (ITypeDiscoveryService)serviceProvider
            .GetService(typeof(ITypeDiscoveryService));
        var types = typeDiscoverySvc.GetTypes(typeof(object), true)
            .Cast<Type>().Where(item =>
                item.IsPublic &&
                typeof(T).IsAssignableFrom(item) &&
                !item.IsAbstract &&
                !item.FullName.StartsWith("System")
            ).ToList();
        return types;
    }
    private Type GetTypeFromName(IServiceProvider 
        serviceProvider, string typeName)
    {
        ITypeResolutionService typeResolutionSvc =
            (ITypeResolutionService)serviceProvider
            .GetService(typeof(ITypeResolutionService));
        return typeResolutionSvc.GetType(typeName);
    }
}

