User Control Property that shows a list of all Forms at design time

前端 未结 1 2028
一向
一向 2021-01-15 06:44

As we all know Forms created with Form.cs file

I have property of type Form

example : public Form TargetForm {get;set;}

相关标签:
1条回答
  • 2021-01-15 07:14

    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:

    • TypeConverter: Provides a unified way of converting types of values to other types, as well as for accessing standard values and subproperties.

    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);
        }
    }
    
    0 讨论(0)
提交回复
热议问题