C# 泛型方法反射呼叫窗體
阿新 • • 發佈:2019-02-04
//Create By ChimHsiung;
//Begin 2016-10
//Last 2017-06
主介面窗體呼叫方法的設計變更歷程:
一、原始方法,每個窗體一個類手動呼叫。弊端:一個系統動輒上百個類,程式碼量大不說,變更調整也不省事。
switch (frmName) { case "frmNavigate": frmNavigate fnav = new frmNavigate(); fnav.MdiParent = this; fnav.Show(); break; case "frmEmployee"://員工資料 frmEmployee femp = new frmEmployee(); femp.MdiParent = this; femp.Show(); break; case "frmModal"://模組管理 frmModal fmod = new frmModal(); fmod.MdiParent = this; fmod.Show(); break; case "frmField"://欄位列管理 frmField ffld = new frmField(); ffld.MdiParent = this; ffld.Show(); break; default: break; }
二、通過類名反射呼叫窗體,每個呼叫物件都設定好主類名及虛擬類名。主窗體呼叫時無須一個個類名寫呼叫
,另外增加虛擬通用類設計
//遍歷全部DLL窗體 string dir = Directory.GetCurrentDirectory(); foreach (var file in Directory.GetFiles(dir + @"\", "*.dll")) { //排除Dev控制元件的DLL檔案 FileInfo fi = new FileInfo(file); if(fi.Name.Length>=10 && fi.Name.Substring(0, 10) == "DevExpress") continue; //MessageBox.Show(file); System.Reflection.Assembly a = System.Reflection.Assembly.LoadFile(file); Type[] types = a.GetTypes(); foreach (Type t in types) { if (t.BaseType == typeof(frmBaseList)) { if (t.Name == frmName) { var fbl = Activator.CreateInstance(t) as frmBaseList; fbl.MdiParent = this; fbl.Show(); //MessageBox.Show(file); //MessageBox.Show(t.Name); //Form fm = t.BaseType as Form; } } } }
三、優化上一版本BUG,原因為DLL檔案呼叫到其他非專案庫時異常,改為手動指定DLL檔案列表
foreach(string file in SysParam.Sys_DllList) { System.Reflection.Assembly a = System.Reflection.Assembly.UnsafeLoadFrom(Directory.GetCurrentDirectory() + @"\" + file); Type[] types = a.GetTypes(); foreach (Type t in types) { if (t.BaseType == typeof(Form)) { if (t.Name == frmName) { try { var fbl = Activator.CreateInstance(t) as Form; if (IsMdi) fbl.MdiParent = this; else fbl.StartPosition = FormStartPosition.CenterScreen; fbl.Text = frmText; fbl.Show(); return; } catch (Exception ex) { MessageBox.Show(ex.Message); return; } } } } }
四、最終版本 泛型反射呼叫 只為集中設計處理 /// <summary> /// 泛型方法反射呼叫窗體 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="frmName"></param> /// <param name="frmType"></param> /// <returns></returns> public static T AssemblyForm<T>(string frmName) { try { string dir = Directory.GetCurrentDirectory(); foreach (string file in SysData.SysParam.Sys_DllList) { System.Reflection.Assembly a = System.Reflection.Assembly.UnsafeLoadFrom(Directory.GetCurrentDirectory() + @"\" + file); Type[] types = a.GetTypes(); foreach (Type t in types) { if (t.BaseType == typeof(T)) { if (t.Name == frmName) { //(typeof.MakeGenericType(T) object fdl = Activator.CreateInstance(t); return (T)fdl; } } } } } catch (Exception ex) { MessageBox.Show(ex.Message, "呼叫窗體異常", MessageBoxButtons.OK, MessageBoxIcon.Error); } return default(T); }
//Begin 2016-10
//Last 2017-06
主介面窗體呼叫方法的設計變更歷程:
一、原始方法,每個窗體一個類手動呼叫。弊端:一個系統動輒上百個類,程式碼量大不說,變更調整也不省事。
switch (frmName) { case "frmNavigate": frmNavigate fnav = new frmNavigate(); fnav.MdiParent = this; fnav.Show(); break; case "frmEmployee"://員工資料 frmEmployee femp = new frmEmployee(); femp.MdiParent = this; femp.Show(); break; case "frmModal"://模組管理 frmModal fmod = new frmModal(); fmod.MdiParent = this; fmod.Show(); break; case "frmField"://欄位列管理 frmField ffld = new frmField(); ffld.MdiParent = this; ffld.Show(); break; default: break; }
二、通過類名反射呼叫窗體,每個呼叫物件都設定好主類名及虛擬類名。主窗體呼叫時無須一個個類名寫呼叫
,另外增加虛擬通用類設計
//遍歷全部DLL窗體 string dir = Directory.GetCurrentDirectory(); foreach (var file in Directory.GetFiles(dir + @"\", "*.dll")) { //排除Dev控制元件的DLL檔案 FileInfo fi = new FileInfo(file); if(fi.Name.Length>=10 && fi.Name.Substring(0, 10) == "DevExpress") continue; //MessageBox.Show(file); System.Reflection.Assembly a = System.Reflection.Assembly.LoadFile(file); Type[] types = a.GetTypes(); foreach (Type t in types) { if (t.BaseType == typeof(frmBaseList)) { if (t.Name == frmName) { var fbl = Activator.CreateInstance(t) as frmBaseList; fbl.MdiParent = this; fbl.Show(); //MessageBox.Show(file); //MessageBox.Show(t.Name); //Form fm = t.BaseType as Form; } } } }
三、優化上一版本BUG,原因為DLL檔案呼叫到其他非專案庫時異常,改為手動指定DLL檔案列表
foreach(string file in SysParam.Sys_DllList) { System.Reflection.Assembly a = System.Reflection.Assembly.UnsafeLoadFrom(Directory.GetCurrentDirectory() + @"\" + file); Type[] types = a.GetTypes(); foreach (Type t in types) { if (t.BaseType == typeof(Form)) { if (t.Name == frmName) { try { var fbl = Activator.CreateInstance(t) as Form; if (IsMdi) fbl.MdiParent = this; else fbl.StartPosition = FormStartPosition.CenterScreen; fbl.Text = frmText; fbl.Show(); return; } catch (Exception ex) { MessageBox.Show(ex.Message); return; } } } } }
四、最終版本 泛型反射呼叫 只為集中設計處理 /// <summary> /// 泛型方法反射呼叫窗體 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="frmName"></param> /// <param name="frmType"></param> /// <returns></returns> public static T AssemblyForm<T>(string frmName) { try { string dir = Directory.GetCurrentDirectory(); foreach (string file in SysData.SysParam.Sys_DllList) { System.Reflection.Assembly a = System.Reflection.Assembly.UnsafeLoadFrom(Directory.GetCurrentDirectory() + @"\" + file); Type[] types = a.GetTypes(); foreach (Type t in types) { if (t.BaseType == typeof(T)) { if (t.Name == frmName) { //(typeof.MakeGenericType(T) object fdl = Activator.CreateInstance(t); return (T)fdl; } } } } } catch (Exception ex) { MessageBox.Show(ex.Message, "呼叫窗體異常", MessageBoxButtons.OK, MessageBoxIcon.Error); } return default(T); }