As we all know Forms created with Form.cs file
I have property of type Form
example : public Form TargetForm {get;set;}
There are two services that can help you at design-time to discover and resolve all types in the solution:
ITypeDiscoveryService: Discovers available types at design time.
ITypeResolutionService: Provides an interface to retrieve an assembly or type by name.
In the other hand, to show standard values in a dropdown in property editor, you can create a TypeConverter
:
Knowing about above options, you can create a custom type converter to discover all form types in the project and list in the dropdown.
Example
In the following example, I've created a custom button class which allows you to select a form type in design type and then at run-time, if you click on the button it shows the selected form as dialog:
To see a VB.NET version for this answer see this post.
MyButton
using System;
using System.ComponentModel;
using System.Windows.Forms;
public class MyButton : Button
{
[TypeConverter(typeof(FormTypeConverter))]
public Type Form { get; set; }
protected override void OnClick(EventArgs e)
{
base.OnClick(e);
if (Form != null && typeof(Form).IsAssignableFrom(Form))
{
using (var f = (Form)Activator.CreateInstance(Form))
f.ShowDialog();
}
}
}
FormTypeConverter
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Globalization;
using System.Linq;
using System.Windows.Forms;
public class FormTypeConverter : 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);
}
}