繁体   English   中英

在设计时显示所有 Forms 列表的用户控件属性

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

众所周知,Forms 是用 Form.cs 文件创建的

我有Form类型的属性

示例: public Form TargetForm {get;set;}

我不需要使用 Activiator.CreateInstance() 来创建表单我只需要从 Forms.cs 文件中选择一个表单并将其附加到 TargetForm 的属性中。

请参阅屏幕截图http://prntscr.com/pmuxdd

提示我想可能对读者有用:TypeDescriptors、Attributes 可能会返回 Visual Studio 解决方案中的类列表。

众所周知, ComponentModel API 很难处理。 所以请不要为此感到难过。

有两种服务可以帮助您在设计时发现和解决解决方案中的所有类型:

另一方面,要在属性编辑器的下拉列表中显示标准值,您可以创建一个TypeConverter

  • TypeConverter提供将值类型转换为其他类型以及访问标准值和子属性的统一方法。

了解上述选项后,您可以创建自定义类型转换器以发现项目中的所有表单类型并在下拉列表中列出。

例子

在下面的示例中,我创建了一个自定义按钮 class ,它允许您在设计类型中 select 一个表单类型,然后在运行时,如果您单击该按钮,它会将所选表单显示为对话框:

在此处输入图像描述

要查看此答案的 VB.NET 版本,请参阅此帖子

我的按钮

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();
        }
    }
}

表单类型转换器

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);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM