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);
}
}
这篇关于在设计时显示所有表单列表的用户控件属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:在设计时显示所有表单列表的用户控件属性
基础教程推荐
- 如何在 IDE 中获取 Xamarin Studio C# 输出? 2022-01-01
- c# Math.Sqrt 实现 2022-01-01
- 将 XML 转换为通用列表 2022-01-01
- 为什么Flurl.Http DownloadFileAsync/Http客户端GetAsync需要 2022-09-30
- rabbitmq 的 REST API 2022-01-01
- 将 Office 安装到 Windows 容器 (servercore:ltsc2019) 失败,错误代码为 17002 2022-01-01
- 如何激活MC67中的红灯 2022-01-01
- SSE 浮点算术是否可重现? 2022-01-01
- 有没有办法忽略 2GB 文件上传的 maxRequestLength 限制? 2022-01-01
- MS Visual Studio .NET 的替代品 2022-01-01