C# 显示设计时所有窗体列表的用户控件属性
我们都知道使用Form.cs文件创建的表单 我的属性类型为C# 显示设计时所有窗体列表的用户控件属性,c#,.net,winforms,user-controls,windows-forms-designer,C#,.net,Winforms,User Controls,Windows Forms Designer,我们都知道使用Form.cs文件创建的表单 我的属性类型为Form 示例:public Form TargetForm{get;set;} 我不需要使用Activator.CreateInstance()来创建表单 我只需要从Forms.cs文件中选择一个表单,并将其附加到TargetForm属性 见截图 小贴士我想可能对读者有用: 类型描述符、属性,可能返回VisualStudio解决方案中的类列表 众所周知,组件模型API很难处理。因此,请不要为此感到难过。有两项服务可以帮助您在设计时发现并
Form
示例:public Form TargetForm{get;set;}
我不需要使用Activator.CreateInstance()来创建表单
我只需要从Forms.cs文件中选择一个表单,并将其附加到TargetForm属性
见截图
小贴士我想可能对读者有用:
类型描述符、属性,可能返回VisualStudio解决方案中的类列表
众所周知,组件模型API很难处理。因此,请不要为此感到难过。有两项服务可以帮助您在设计时发现并解决解决方案中的所有类型:
- :在设计时发现可用类型
- :提供按名称检索程序集或类型的接口
类型转换器
:
- :提供将值类型转换为其他类型以及访问标准值和子属性的统一方法
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用System.ComponentModel.Design;
利用制度全球化;
使用System.Linq;
使用System.Windows.Forms;
公共类FormTypeConverter:TypeConverter
{
公共覆盖布尔GetStandardValues结论
(ITypeDescriptorContext上下文)
{
返回true;
}
公共覆盖布尔CanConvertTo
(ITypeDescriptorContext pContext,类型pDestinationType)
{
return base.CanConvertTo(pContext,pDestinationType);
}
公共覆盖对象转换为
(ITypeDescriptorContext pContext,CultureInfo pCulture,
对象pValue,类型pDestinationType)
{
返回base.ConvertTo(pContext、pCulture、pValue、pDestinationType);
}
公共覆盖布尔CanConvertFrom(ITypeDescriptorContext pContext,
类型pSourceType)
{
if(pSourceType==typeof(string))
返回true;
return base.CanConvertFrom(pContext,pSourceType);
}
公共重写对象转换自
(ITypeDescriptorContext pContext,CultureInfo pCulture,object pValue)
{
if(pValue是字符串)
返回GetTypeFromName(pContext,(string)pValue);
返回base.ConvertFrom(pContext、pCulture、pValue);
}
支持公共覆盖布尔GetStandardValues
(ITypeDescriptorContext pContext)
{
返回true;
}
公共覆盖标准值集合GetStandardValues
(ITypeDescriptorContext pContext)
{
列表类型=GetProjectTypes(pContext);
列表值=新列表();
foreach(类型中的类型)
value.Add(type.FullName);
value.Sort();
返回新的标准值集合(值);
}
私有列表GetProjectTypes(IServiceProvider服务提供商)
{
var typeDiscoverySvc=(ITypeDiscoveryService)服务提供者
.GetService(类型of(ITypeDiscoveryService));
var types=typeDiscoverySvc.GetTypes(typeof(object),true)
.Cast()
。其中(项目=>
item.IsPublic&&
类型(表格)。IsAssignableFrom(项目)&&
!item.FullName.StartsWith(“系统”)
).ToList();
返回类型;
}
私有类型GetTypeFromName(IServiceProvider服务提供程序,字符串类型名称)
{
ITypeResolutionService typeResolutionSvc=(ITypeResolutionService)服务提供商
.GetService(类型of(ITypeResolutionService));
返回typeResolutionSvc.GetType(typeName);
}
}
我几天前刚刚回答。这几乎是一个完全相同的版本,但它是为VB.NET设计的。代码应该很容易转换成C语言。艾哈迈德,我尝试了所有的方法,但是它显示了空的表单列表。谢谢雷扎,你在组件模型中的回答总是很棒的。请你告诉我,我如何能熟练的类型描述符和这件事?有那本书吗?以及你对这些事情的深刻认识。我假设75%的程序员对组件模型一无所知。你调试过标准库吗:)非常欢迎:)我知道的关于设计时支持的大部分内容。或者,我从microsoft文档和.Net Framework中Windows窗体的源代码中学到了。在代码中,你只需要更改typeof(Form)。IsAssignableFrom(item)
至类型(您的用户控件)。IsAssignableFrom(项目)
。但请记住:(1)此解决方案适用于将属性定义为公共类型属性{get;set;}
的情况。如果您希望将属性作为public YourUserControl属性{get;set;}
,在这种情况下,不使用任何TypeConverter
属性,设计器将列出您在表单上放置的YourUserControl
的所有实例。(2)有时,当您更改与设计器相关的类时,您需要关闭所有设计器窗口,清理并重新生成解决方案。(3) 在某些情况下,您需要关闭VS甚至。(4) 事实上,你做了所有这些事情,但问题仍然存在,你可能想要。没问题。希望有帮助:)
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);
}
}