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

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

  

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

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

  有木有想过...

 

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

 

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

 

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

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

 


基础方法

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

C#中通过反射方法获取控件类型和名称
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

图像相关帮助类

C#中通过反射方法获取控件类型和名称
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(0, 1) == Convert.ToChar(34).ToString()

                ? sProg.Substring(1, sProg.IndexOf(Convert.ToChar(34), 2) - 1)

                : sProg.Substring(0, sProg.IndexOf(" ", 2));

            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[0] == '.')

                {

                    //读系统注册表中文件类型信息

                    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 != 2)

                {

                    //系统注册表中注册的标图不能直接提取,则返回可执行文件的通用图标

                    fileIcon = new[] { systemDirectory + "shell32.dll", "2" };

                }

                Icon resultIcon = null;

                try

                {

                    //调用API方法读取图标

                    var phiconLarge = new int[1];

                    var phiconSmall = new int[1];

                    ExtractIconEx(fileIcon[0], Int32.Parse(fileIcon[1]), phiconLarge, phiconSmall, 1);

                    var IconHnd = new IntPtr(isLarge ? phiconLarge[0] : phiconSmall[0]);

                    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[1];

                        var phiconSmall = new int[1];

                        ExtractIconEx(fileIcon[0], Int32.Parse(fileIcon[1]), phiconLarge, phiconSmall, 1);

                        var IconHnd = new IntPtr(isLarge ? phiconLarge[0] : phiconSmall[0]);

                        resultIcon = Icon.FromHandle(IconHnd);

                    }

                }

                return resultIcon;

            }



            return null;

        }



    }

}
SystemIconHelper

自定义属性的类

C#中通过反射方法获取控件类型和名称
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中

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;

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 > 0)

                {

                    name = customAttributes[0].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(0, 0);

            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(524, 391);

            this.splitContainer1.SplitterDistance = 178;

            this.splitContainer1.TabIndex = 1;

            // 

            // mainTree

            // 

            this.mainTree.Dock = System.Windows.Forms.DockStyle.Fill;

            this.mainTree.Location = new System.Drawing.Point(0, 0);

            this.mainTree.Name = "mainTree";

            this.mainTree.Size = new System.Drawing.Size(178, 391);

            this.mainTree.TabIndex = 0;

            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(524, 391);

            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#中通过反射方法获取控件类型和名称

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(52, 49);

            this.label1.Name = "label1";

            this.label1.Size = new System.Drawing.Size(41, 12);

            this.label1.TabIndex = 0;

            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#中通过反射方法获取控件类型和名称

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(39, 29);

            this.button1.Name = "button1";

            this.button1.Size = new System.Drawing.Size(75, 23);

            this.button1.TabIndex = 0;

            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#中通过反射方法获取控件类型和名称

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(98, 37);

            this.checkBox1.Name = "checkBox1";

            this.checkBox1.Size = new System.Drawing.Size(78, 16);

            this.checkBox1.TabIndex = 0;

            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(284, 262);

            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#中通过反射方法获取控件类型和名称

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(94, 63);

            this.button1.Name = "button1";

            this.button1.Size = new System.Drawing.Size(75, 23);

            this.button1.TabIndex = 0;

            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(284, 262);

            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#中通过反射方法获取控件类型和名称


 

 

做一个快乐的程序员

 

你可能感兴趣的:(C#)