C#中通过反射方法获取控件类型和名称

时间:2021-03-21 14:52:56

  这个方法是简单的也是神奇的。

  

  有木有想过,将自己项目中的所有类型,包括自定义类型的命名空间和名称全部获取出来?

  有木有想过,有一种简便的方法可以自动化管理项目中的控件和窗体?

  有木有想过...

  首先,要敢想、要敢尝试。

通过以下方法,进行简单变换,是可以做到本程序控制本项目的窗体和控件。

以下方法简单了,就不一一说明了,如果你觉得有用,全部复制了编译一下,看看就明白是怎么反射了。

当然懂得大大们看到我有不足之处,请不要谩骂了,我脸皮薄,被你们骂骂就泄气了,技术有限,请大大们不吝赐教。


基础方法

通过反射获取项目中所有类型(重点)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms; namespace BackgroundManager.Func
{
public class GetAssemblyClass
{
static Type[] _assemblyArray;
readonly static Object lockObject = new Object(); public Type[] GetAssembly()
{
if (_assemblyArray == null)
{
lock (lockObject)
{
_assemblyArray = Assembly.GetExecutingAssembly().GetTypes();
}
}
return _assemblyArray;
} public Type[] GetFormAssembly()
{
Type[] assemblyArray = GetAssembly();
string allType = typeof(Form).FullName;
string mainType = typeof(frmMain).FullName;
return Array.FindAll(assemblyArray, delegate(Type type)
{
return (type.BaseType.FullName == allType && type.FullName != mainType);
});
} public Type[] GetUserCtlAssembly()
{
Type[] assemblyArray = GetAssembly();
string allType = typeof(UserControl).FullName;
string mainType = typeof(frmMain).FullName;
return Array.FindAll(assemblyArray, delegate(Type type)
{
return (type.BaseType.FullName == allType && type.FullName != mainType);
});
}
}
}

GetAssemblyClass

图像相关帮助类

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Win32; namespace BackgroundManager.Func
{
public class SystemIconHelper
{
[DllImport("shell32.dll")]
public static extern uint ExtractIconEx(string lpszFile, int nIconIndex, int[] phiconLarge,
int[] phiconSmall, uint nIcons); [DllImport("gdi32.dll")]
private static extern bool DeleteObject(IntPtr hObject); public static Dictionary<String, Icon> IconList = new Dictionary<String, Icon>(); /// <summary>
/// Image转换为Icon
/// </summary>
/// <param name="orgImg"></param>
/// <returns></returns>
public static Icon ImageToIcon(Image orgImg)
{
var bmp = new Bitmap(orgImg);
IntPtr h = bmp.GetHicon();
Icon icon = Icon.FromHandle(h);
// 释放IntPtr
DeleteObject(h);
return icon;
} /// <summary>
/// Image 转化为 字节流
/// </summary>
/// <param name="image"></param>
/// <param name="Format"></param>
/// <returns></returns>
public static byte[] ImageToByteArray(Image image, ImageFormat Format)
{
var ms = new MemoryStream();
image.Save(ms, ImageFormat.Png);
return ms.ToArray();
} /// <summary>
/// 字节流 转化为 Image
/// </summary>
/// <param name="btArray"></param>
/// <returns></returns>
public static Image ImageFromByteArray(byte[] btArray)
{
var ms = new MemoryStream(btArray);
Image returnImage = Image.FromStream(ms);
return returnImage;
} /// <summary>
/// 获取文件内容的类型
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public static string GetContentType(string fileName)
{
string contentType = "application/octetstream";
try
{
string ext = Path.GetExtension(fileName).ToLower();
RegistryKey registryKey = Registry.ClassesRoot.OpenSubKey(ext);
if (registryKey != null && registryKey.GetValue("Content Type") != null)
contentType = registryKey.GetValue("Content Type").ToString();
}
catch (Exception)
{ }
return contentType;
} /// <summary>
/// 根据文件的类型获取 Icon
/// </summary>
/// <param name="sFileExt"></param>
/// <returns></returns>
public static Icon GetIconByFileType(String sFileExt)
{
string sProg =
Registry.ClassesRoot.OpenSubKey(Registry.ClassesRoot.OpenSubKey(sFileExt).GetValue(String.Empty).ToString())
.OpenSubKey("shell")
.OpenSubKey("open")
.OpenSubKey("command")
.GetValue(String.Empty)
.ToString();
sProg = sProg.Substring(, ) == Convert.ToChar().ToString()
? sProg.Substring(, sProg.IndexOf(Convert.ToChar(), ) - )
: sProg.Substring(, sProg.IndexOf(" ", ));
sProg = sProg.Replace("%1", String.Empty);
Icon oIcon = Icon.ExtractAssociatedIcon(sProg);
return oIcon;
} /// <summary>
/// 根据文件名获得图片数组下标
/// </summary>
/// <param name="fileName"></param>
/// <param name="isLarge"></param>
/// <returns></returns>
public static Icon GetIconByFileName(String fileName, bool isLarge)
{
String GetIcon = new FileInfo(fileName).Extension;
if (IconList.ContainsKey(GetIcon))
{
return IconList[GetIcon];
} Icon mIcon = GetIconByFileType(GetIcon, isLarge);
if (mIcon != null)
{
IconList.Add("GetIcon", mIcon);
return mIcon;
} return null;
} /// <summary>
/// 给出文件扩展名(.*),返回相应图标
/// 若不以"."开头则返回文件夹的图标。
/// </summary>
/// <param name="fileType"></param>
/// <param name="isLarge"></param>
/// <returns></returns>
public static Icon GetIconByFileType(string fileType, bool isLarge)
{
if (!string.IsNullOrEmpty(fileType))
{
string regIconString = null;
//默认指定为文件夹图标
string systemDirectory = Environment.SystemDirectory + "\\shell32.dll,3"; if (fileType[] == '.')
{
//读系统注册表中文件类型信息
RegistryKey regVersion = Registry.ClassesRoot.OpenSubKey(fileType, true);
if (regVersion != null)
{
string regFileType = regVersion.GetValue(String.Empty) as String;
regVersion.Close();
regVersion = Registry.ClassesRoot.OpenSubKey(regFileType + @"\DefaultIcon", true);
if (regVersion != null)
{
regIconString = regVersion.GetValue(String.Empty) as String;
regVersion.Close();
}
}
if (regIconString == null)
{
//没有读取到文件类型注册信息,指定为未知文件类型的图标
regIconString = systemDirectory + "shell32.dll,0";
}
}
String[] fileIcon = regIconString.Split(new[] { ',' });
if (fileIcon.Length != )
{
//系统注册表中注册的标图不能直接提取,则返回可执行文件的通用图标
fileIcon = new[] { systemDirectory + "shell32.dll", "" };
}
Icon resultIcon = null;
try
{
//调用API方法读取图标
var phiconLarge = new int[];
var phiconSmall = new int[];
ExtractIconEx(fileIcon[], Int32.Parse(fileIcon[]), phiconLarge, phiconSmall, );
var IconHnd = new IntPtr(isLarge ? phiconLarge[] : phiconSmall[]);
resultIcon = Icon.FromHandle(IconHnd);
}
catch
{
try
{
//第二方案
resultIcon = GetIconByFileType(fileType);
}
catch
{
//默认方案
regIconString = systemDirectory + "shell32.dll,0";
fileIcon = regIconString.Split(new[] { ',' });
resultIcon = null;
//调用API方法读取图标
var phiconLarge = new int[];
var phiconSmall = new int[];
ExtractIconEx(fileIcon[], Int32.Parse(fileIcon[]), phiconLarge, phiconSmall, );
var IconHnd = new IntPtr(isLarge ? phiconLarge[] : phiconSmall[]);
resultIcon = Icon.FromHandle(IconHnd);
}
}
return resultIcon;
} return null;
} }
}

SystemIconHelper

自定义属性的类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace BackgroundManager
{
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class MyAttribute : Attribute
{
private string _name = "";
private string _display = "";
private string _value = ""; public MyAttribute(string name, string value, string display)
{
_name = name;
_value = value;
_display = display;
} public string Value
{
get { return _value; }
set { _value = value; }
}
public string Display
{
get { return _display; }
set { _display = value; }
}
public string Name
{
get { return _name; }
set { _name = value; }
}
}
}

MyAttribute


frmMain主窗体

  Application.Run(new frmMain());   为了减少篇幅,就没写这个,但它作为主窗体启动。

  mainTree 上的节点是通过反射获取到所有控件和窗体,然后将它们加入到mainTree中

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using BackgroundManager.Func; namespace BackgroundManager
{
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
this.IsMdiContainer = true; InitTreeList();
} private void InitTreeList()
{
GetAssemblyClass getass = new GetAssemblyClass();
Type[] frmTypes = getass.GetFormAssembly();
Type[] ctlTypes = getass.GetUserCtlAssembly();
mainTree.Nodes.Clear(); var typeArray = new List<Type>();
typeArray.AddRange(frmTypes);
typeArray.AddRange(ctlTypes);
foreach (Type type in typeArray)
{
TreeNode node;
string name = type.Name;
MyAttribute[] customAttributes = type.GetCustomAttributes(typeof(MyAttribute), true) as MyAttribute[];
if (customAttributes != null && customAttributes.Length > )
{
name = customAttributes[].Display;
}
node = new TreeNode(name);
node.Tag = type;
mainTree.Nodes.Add(node);
}
} private void mainTree_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{ } private void mainTree_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
{
if (e.Node != null)
{
Type t = e.Node.Tag as Type;
if (t != null)
{
UserControl c = Activator.CreateInstance(t) as UserControl;
if (c != null)
{
this.splitContainer1.Panel2.Controls.Clear();
this.splitContainer1.Panel2.Controls.Add(c);
c.Dock = DockStyle.Fill;
} Form c2 = Activator.CreateInstance(t) as Form;
if (c2 != null)
{
c2.MdiParent = this;
this.splitContainer1.Panel2.Controls.Clear();
this.splitContainer1.Panel2.Controls.Add(c2);
c2.Dock = DockStyle.Fill;
c2.Show();
}
}
}
} /// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null; /// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
} #region Windows 窗体设计器生成的代码 /// <summary>
/// 设计器支持所需的方法 - 不要
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(frmMain));
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
this.mainTree = new System.Windows.Forms.TreeView();
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
this.splitContainer1.Panel1.SuspendLayout();
this.splitContainer1.SuspendLayout();
this.SuspendLayout();
//
// splitContainer1
//
this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitContainer1.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
this.splitContainer1.Location = new System.Drawing.Point(, );
this.splitContainer1.Name = "splitContainer1";
//
// splitContainer1.Panel1
//
this.splitContainer1.Panel1.AutoScroll = true;
this.splitContainer1.Panel1.Controls.Add(this.mainTree);
//
// splitContainer1.Panel2
//
this.splitContainer1.Panel2.AutoScroll = true;
this.splitContainer1.Size = new System.Drawing.Size(, );
this.splitContainer1.SplitterDistance = ;
this.splitContainer1.TabIndex = ;
//
// mainTree
//
this.mainTree.Dock = System.Windows.Forms.DockStyle.Fill;
this.mainTree.Location = new System.Drawing.Point(, );
this.mainTree.Name = "mainTree";
this.mainTree.Size = new System.Drawing.Size(, );
this.mainTree.TabIndex = ;
this.mainTree.NodeMouseClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.mainTree_NodeMouseClick);
this.mainTree.NodeMouseDoubleClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.mainTree_NodeMouseDoubleClick);
//
// frmMain
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.AutoSize = true;
this.BackColor = System.Drawing.SystemColors.Control;
this.ClientSize = new System.Drawing.Size(, );
this.Controls.Add(this.splitContainer1);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.Name = "frmMain";
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "后台管理";
this.splitContainer1.Panel1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
this.splitContainer1.ResumeLayout(false);
this.ResumeLayout(false); } #endregion private System.Windows.Forms.SplitContainer splitContainer1;
private System.Windows.Forms.TreeView mainTree; }
}

frmMain

 请注意  this.IsMdiContainer = true;


以下四个类为测试控件

C#中通过反射方法获取控件类型和名称

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms; namespace BackgroundManager.GUI
{
[MyAttribute("","","test1")]
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
} /// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null; /// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
} #region 组件设计器生成的代码 /// <summary>
/// 设计器支持所需的方法 - 不要
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(, );
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(, );
this.label1.TabIndex = ;
this.label1.Text = "label1";
//
// UserControl1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.label1);
this.Name = "UserControl1";
this.ResumeLayout(false);
this.PerformLayout(); } #endregion private System.Windows.Forms.Label label1;
}
}

UserControl1

C#中通过反射方法获取控件类型和名称

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms; namespace BackgroundManager.GUI
{
public partial class UserControl3 : UserControl
{
public UserControl3()
{
InitializeComponent();
} /// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null; /// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
} #region 组件设计器生成的代码 /// <summary>
/// 设计器支持所需的方法 - 不要
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(, );
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(, );
this.button1.TabIndex = ;
this.button1.Text = "button1";
this.button1.UseVisualStyleBackColor = true;
//
// UserControl3
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.button1);
this.Name = "UserControl3";
this.ResumeLayout(false); } #endregion private System.Windows.Forms.Button button1;
}
}

UserControl3

C#中通过反射方法获取控件类型和名称

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms; namespace BackgroundManager.GUI
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} /// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null; /// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
} #region Windows Form Designer generated code /// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.checkBox1 = new System.Windows.Forms.CheckBox();
this.SuspendLayout();
//
// checkBox1
//
this.checkBox1.AutoSize = true;
this.checkBox1.Location = new System.Drawing.Point(, );
this.checkBox1.Name = "checkBox1";
this.checkBox1.Size = new System.Drawing.Size(, );
this.checkBox1.TabIndex = ;
this.checkBox1.Text = "checkBox1";
this.checkBox1.UseVisualStyleBackColor = true;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(, );
this.ControlBox = false;
this.Controls.Add(this.checkBox1);
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
this.PerformLayout(); } #endregion private System.Windows.Forms.CheckBox checkBox1;
}
}

Form1

C#中通过反射方法获取控件类型和名称

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms; namespace BackgroundManager.GUI
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
} /// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null; /// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
} #region Windows Form Designer generated code /// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(, );
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(, );
this.button1.TabIndex = ;
this.button1.Text = "button1";
this.button1.UseVisualStyleBackColor = true;
//
// Form2
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(, );
this.Controls.Add(this.button1);
this.Name = "Form2";
this.Text = "Form2";
this.ResumeLayout(false); } #endregion private System.Windows.Forms.Button button1;
}
}

Form2


生成后运行界面:

C#中通过反射方法获取控件类型和名称C#中通过反射方法获取控件类型和名称

这里我们选择的是userControl1,为什么在mainTree中显示的是test1,请仔细看UserControl1中的这段:    [MyAttribute("","","test1")],这样可以灵活方便控制控件名称

C#中通过反射方法获取控件类型和名称C#中通过反射方法获取控件类型和名称


做一个快乐的程序员