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

图像相关帮助类

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

自定义属性的类

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 > 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;


 

以下四个类为测试控件

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

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

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

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

生成后运行界面:

 

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


 

 

做一个快乐的程序员

 

posted @ 2014-12-15 18:09  牧师/preacher  阅读(19309)  评论(3编辑  收藏  举报