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

User Control Property that shows a list of all Forms at design time(在设计时显示所有表单列表的用户控件属性)
本文介绍了在设计时显示所有表单列表的用户控件属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

众所周知,使用 Form.cs 文件创建的表单

我有 Form

类型的属性

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

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

查看截图

<块引用>

要查看此答案的 VB.NET 版本,请参阅这篇文章.

我的按钮

使用系统;使用 System.ComponentModel;使用 System.Windows.Forms;公共类 MyButton : 按钮{[TypeConverter(typeof(FormTypeConverter))]公共类型表格{获取;放;}受保护的覆盖无效 OnClick(EventArgs e){base.OnClick(e);if (Form != null && typeof(Form).IsAssignableFrom(Form)){使用 (var f = (Form)Activator.CreateInstance(Form))f.ShowDialog();}}}

FormTypeConverter

使用系统;使用 System.Collections.Generic;使用 System.ComponentModel;使用 System.ComponentModel.Design;使用 System.Globalization;使用 System.Linq;使用 System.Windows.Forms;公共类 FormTypeConverter : TypeConverter{公共覆盖布尔 GetStandardValuesExclusive(ITypeDescriptorContext 上下文){返回真;}公共覆盖布尔 CanConvertTo(ITypeDescriptorContext pContext,类型 pDestinationType){返回 base.CanConvertTo(pContext, pDestinationType);}公共覆盖对象 ConvertTo(ITypeDescriptorContext pContext,CultureInfo pCulture,对象 pValue,类型 pDestinationType){返回 base.ConvertTo(pContext, pCulture, pValue, pDestinationType);}公共覆盖 bool CanConvertFrom(ITypeDescriptorContext pContext,类型 pSourceType){if (pSourceType == typeof(string))返回真;返回 base.CanConvertFrom(pContext, pSourceType);}公共覆盖对象 ConvertFrom(ITypeDescriptorContext pContext、CultureInfo pCulture、对象 pValue){if (pValue 是字符串)返回 GetTypeFromName(pContext, (string)pValue);返回 base.ConvertFrom(pContext, pCulture, pValue);}公共覆盖布尔 GetStandardValuesSupported(ITypeDescriptorContext pContext){返回真;}公共覆盖 StandardValuesCollection GetStandardValues(ITypeDescriptorContext pContext){列表<类型>类型 = GetProjectTypes(pContext);列表<字符串>值 = 新列表<字符串>();foreach(类型中的类型)values.Add(type.FullName);值.排序();返回新的 StandardValuesCollection(值);}私有列表<类型>GetProjectTypes(IServiceProvider serviceProvider){var typeDiscoverySvc = (ITypeDiscoveryService)serviceProvider.GetService(typeof(ITypeDiscoveryService));var types = typeDiscoverySvc.GetTypes(typeof(object), true).Cast<类型>().哪里(项目=>item.IsPublic &&typeof(Form).IsAssignableFrom(item) &&!item.FullName.StartsWith("系统")).ToList();返回类型;}私有类型 GetTypeFromName(IServiceProvider serviceProvider, string typeName){ITypeResolutionService typeResolutionSvc = (ITypeResolutionService)serviceProvider.GetService(typeof(ITypeResolutionService));返回 typeResolutionSvc.GetType(typeName);}}

As we all know Forms created with Form.cs file

I have property of type Form

example : public Form TargetForm {get;set;}

i don't need to use Activiator.CreateInstance() to create Form I just need to choose a Form from Forms.cs files and attach it with property of TargetForm .

See Screenshot http://prntscr.com/pmuxdd

Tips i guess maybe something usefull to readers : TypeDescriptors, Attributes maybe that return a list of classes in Visual Studio Solutions.

As we all know the ComponentModel API is hard to deal with. so please don't feel bad about that.

解决方案

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

这篇关于在设计时显示所有表单列表的用户控件属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
Programmatically show the desktop(以编程方式显示桌面)
c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)