用户控件属性,在设计时显示所有窗体的列表 [英] User Control Property that shows a list of all Forms at design time

查看:131
本文介绍了用户控件属性,在设计时显示所有窗体的列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们都知道用Form.cs文件创建的表单



我拥有 Form类型的属性



示例:公共表单TargetForm {get; set;}



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



请参见截图


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


MyButton

 使用系统; 
使用System.ComponentModel;
使用System.Windows.Forms;
公共类MyButton:按钮
{
[TypeConverter(typeof(FormTypeConverter))]]
公共类型表单{get;组; }

受保护的覆盖无效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
{
公共重写bool GetStandardValuesExclusive
(ITypeDescriptorContext上下文)
{
返回true;
}
公共替代布尔值CanConvertTo
(ITypeDescriptorContext pContext,类型pDestinationType)
{
返回base.CanConvertTo(pContext,pDestinationType);
}
公共替代对象ConvertTo
(ITypeDescriptorContext pContext,CultureInfo pCulture,
对象pValue,类型pDestinationType)
{
返回base.ConvertTo(pContext, pCulture,pValue,pDestinationType);
}
公共替代布尔值CanConvertFrom(ITypeDescriptorContext pContext,
Type pSourceType)
{
if(pSourceType == typeof(string))
返回true;
返回base.CanConvertFrom(pContext,pSourceType);
}
公共替代对象ConvertFrom
(ITypeDescriptorContext pContext,CultureInfo pCulture,对象pValue)
{
if(pValue是string)
return GetTypeFromName(pContext ,(string)pValue);
返回base.ConvertFrom(pContext,pCulture,pValue);
}

公共重写bool GetStandardValuesSupported
(ITypeDescriptorContext pContext)
{
返回true;
}
公共替代StandardValuesCollection GetStandardValues
(ITypeDescriptorContext pContext)
{
List< Type>类型= GetProjectTypes(pContext);
List< string>值=新的List< string>();
foreach(类型中的类型)
values.Add(type.FullName);

值。Sort();
返回新的StandardValuesCollection(values);
}
私人列表< Type> GetProjectTypes(IServiceProvider serviceProvider)
{
var typeDiscoverySvc =(ITypeDiscoveryService)serviceProvider
.GetService(typeof(ITypeDiscoveryService));
var类型= typeDiscoverySvc.GetTypes(typeof(object),true)
.Cast< Type>()
.Where(item =>
item.IsPublic& amp; ;
typeof(Form).IsAssignableFrom(item)&
!item.FullName.StartsWith( System)
).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:

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

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

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆