1 背景
最近在做一个控件工具箱,要填充控件到控件工具箱,就涉及到搜索控件类型的逻辑了。
参考:https://github.com/icsharpcode/WpfDesigner
2 关键代码
2.1 加载程序集
// 加载程序集
var assembly = Assembly.LoadFrom(path);
2.2 获取程序集中定义的所有公共类型
// 获取程序集中定义的所有公共类型
var types = assembly.GetExportedTypes();
2.3判断类型是否为控件
/// <summary>
/// 判断类型t是否为控件
/// </summary>
/// <param name="t">待判断的类型</param>
/// <returns>是否是控件的bool值</returns>
private static bool IsControl(Type t)
{
return !t.IsAbstract && // 非抽象类
!t.IsGenericTypeDefinition && // 非泛型类
t.IsSubclassOf(typeof(UIElement)) && // 是一个UIElement类
t.GetConstructor(BindingFlags.Public | // 包含公共非静态的无参的构造函数
BindingFlags.Instance, null,Type.EmptyTypes, null) != null;
}
3 综合代码
/// <summary>
/// 获取程序集的所有
/// </summary>
/// <param name="assemblyPath"></param>
/// <returns></returns>
private List<Type> GetControlTypes(string assemblyPath)
{
var list = new List<Type>();
var assembly = Assembly.LoadFrom(assemblyPath);
// 获取此程序集中定义的公共类型,这些公共类型在程序集外可见
foreach (var t in assembly.GetExportedTypes())
{
// 判断类型t是否为控件
if (IsControl(t))
{
// 是控件,则添加返回结果
list.Add(t);
}
}
return list;
}
/// <summary>
/// 判断类型t是否为控件
/// </summary>
/// <param name="t">待判断的类型</param>
/// <returns>是否是控件的bool值</returns>
private static bool IsControl(Type t)
{
return !t.IsAbstract && // 非抽象类
!t.IsGenericTypeDefinition && // 非泛型类
t.IsSubclassOf(typeof(UIElement)) && // 是一个UIElement类
t.GetConstructor(BindingFlags.Public | // 包含公共非静态的无参的构造函数
BindingFlags.Instance, null,Type.EmptyTypes, null) != null;
}