Management Studio是我在WinForms小項目開發過程當中搭建起來的一個插件式結構的應用程序框架,由於簡單靈活又容易擴展,如今將它開源供讀者參考。程序員
跑起來的效果圖以下所示,具有選項卡式多文檔界面,Office 2007藍色風格,插件式結構等特性。編程
經過Infragistics Dock控件,能夠很容易的實現選項卡式多文檔界面。只須要在主界面的窗體設計器組件欄中拖入一個ultraTabbedMdiManager控件,設定主窗體的IsMdiContainer屬性爲true,剩下的工做就交由這個組件來負責。多線程
當咱們用下面的代碼建立一個子窗體時,它會自動的產生一個選項卡文檔,參考下面代碼。框架
Startup frm = new Startup();
frm.MdiParent = this;
frm.Show();
從上面的代碼片斷中能夠看到仍舊是MDI的編程風格,但產生的結果是選項卡式的界面。ide
藉助於反射機制,讀取當前程序集中的類型定義,找到包含有指定特性的類型,建立它的實例,便可實現基本的插件式結構。ui
首先,咱們給須要的窗體類增長FunctionCode特性,參考下面的代碼。this
[FunctionCode("DataSetReader")]
public partial class DataSetReader : FormBase
{
public DataSetReader()
{
InitializeComponent();
}
而後修改建立窗體的代碼,從當前的程序集類型中搜索,找到指定特性的窗體的類型後,建立它的實例。關鍵的代碼以下面所示。編碼
Assembly assembly = Assembly.GetExecutingAssembly();
foreach (Type type in assembly.GetTypes())
{
try
{
object[] attributes = type.GetCustomAttributes(typeof(FunctionCode), true);
foreach (object obj in attributes)
{
FunctionCode attribute = (FunctionCode)obj;
if (!string.IsNullOrEmpty(attribute.Value))
{
if (!_formBaseType.ContainsKey(attribute.Value))
_formBaseType.Add(attribute.Value, type);
if (formBaseType == null && attribute.Value.Equals(functionCode,StringComparison.InvariantCultureIgnoreCase))
formBaseType = type;
}
最後,咱們添加一個菜單項,用於顯示當前已經存在的功能編碼給用戶選擇,菜單項的實現用XML文件定義,參考項目中嵌入的資源文件ListItem.xml。spa
<?xml version="1.0" encoding="utf-8" ?>
<Items>
<Item Index="0" Text="DataSet Reader" Tag="DataSetReader" ImageIndex="17"></Item>
<Item Index="1" Text="Translation" Tag="Translation" ImageIndex="32"></Item>
<Item Index="2" Text="String Builder" Tag="TextToStringBuilder" ImageIndex="33"></Item>
<Item Index="3" Text="License Generator" Tag="GenLicense" ImageIndex="7"></Item>
<Item Index="4" Text="Query Generator" Tag="QueryGenerator" ImageIndex="34"></Item>
<Item Index="5" Text="Lookup Generator" Tag="LookupGenerator" ImageIndex="35"></Item>
<Item Index="6" Text="Report Generator" Tag="ReportGenerator" ImageIndex="36"></Item>
<Item Index="7" Text="Query Lookup" Tag="QueueLookUpForm" ImageIndex="37"></Item>
<Item Index="8" Text="Database Update" Tag="DatabaseUpdate" ImageIndex="38"></Item>
</Items>
運行時讀取嵌入的資源項,生成以下界面所示的列表視圖。插件
雙擊列表視圖中的項或選擇項後點OK均可以打開指定的功能對應的窗體。
借用CodeProject上的一篇文章提供的組件,咱們只須要在主界面的OnLoad方法中增長2行代碼便可實現藍色的界面風格。
private void Form1_Load(object sender, EventArgs e)
{
ToolStripManager.Renderer = new ERP.Misc.Office2007Renderer();
statusStrip.Renderer = new ERP.Misc.Office2007Renderer();
Office Render組件已經設置好了默認的顏色風格,並不須要咱們去調整。程序員大多沒有色彩知識,ASP.NET 組件Ext.NET也是一個藍色風格的組件,它內置的藍色風格很受歡迎,程序員不喜歡也沒有能力去維護這個複雜的配色方案,只想拿來用就能夠了。
private static Color _c1 = Color.FromArgb(167, 167, 167);
private static Color _c2 = Color.FromArgb(21, 66, 139);
private static Color _c3 = Color.FromArgb(76, 83, 92);
private static Color _c4 = Color.FromArgb(250, 250, 250);
private static Color _c5 = Color.FromArgb(248, 248, 248);
private static Color _c6 = Color.FromArgb(243, 243, 243);
private static Color _r1 = Color.FromArgb(255, 255, 251);
private static Color _r2 = Color.FromArgb(255, 249, 227);
private static Color _r3 = Color.FromArgb(255, 242, 201);
private static Color _r4 = Color.FromArgb(255, 248, 181);
WorkerThreadBase也是CodeProject上面的一篇文章的代碼。一般與界面相關的長時間的操做咱們應該用BackgroundWorker組件封裝起來以免界面死鎖。若是不是與界面相關的操做,咱們能夠用多線程,並行等方法實現,也能夠用這裏提到的WorkerThreadBase,它的例子代碼以下所示,下面是一個複製文件的例子。
public class CopyFileWorker : WorkerThreadBase
{
private static CopyInfo _copyInfo;
public CopyFileWorker(CopyInfo copyInfo)
{
_copyInfo = copyInfo;
}
protected override void Work()
{
copyFiles(_copyInfo);
}
private void copyFiles(CopyInfo copyInfo)
{
//check if the user called Stop
if (StopRequested)
{
Console.WriteLine("User called Stop.");
Console.WriteLine("Terminating thread while copying directory '{0}'.", copyInfo.Source);
return;
}
if (!Directory.Exists(copyInfo.Destination))
{
Directory.CreateDirectory(copyInfo.Destination);
}
Console.WriteLine("CopyFiles from '{0}' to '{1}' {2}...", copyInfo.Source,copyInfo.Destination, copyInfo.Recursive ? "recursive" : "non-recursive");
foreach (string file in Directory.GetFiles(copyInfo.Source))
{
string destination = Path.Combine(copyInfo.Destination,Path.GetFileName(file));
File.Copy(file, destination);
}
if (copyInfo.Recursive)
{
foreach (string directory in Directory.GetDirectories(copyInfo.Source))
{
string destination = Path.Combine(copyInfo.Destination,Path.GetFileName(directory)); //get the directory name for the path
copyFiles(new CopyInfo(directory,destination,copyInfo.Recursive));
}
}
Console.WriteLine("CopyFiles finished.");
}
繼承於WorkerThreadBase,將要操做的方法放到Work方法中重寫,啓動一個或多個後臺線程任務的例子代碼參考下面的程序片斷。
DummyWorker dummyWorker = new DummyWorker();
dummyWorker.Start();
CopyFileWorker copyFileWorker = new CopyFileWorker(_copyInfo);
copyFileWorker.Start();
//wait for the two threads to finish
WorkerThreadBase.WaitAll(copyFileWorker, dummyWorker);
Management Studio的源代碼包中提供幾個基礎的功能,好比這裏的將字符串轉化爲.NET代碼的功能。這個功能的源代碼來自網友的代碼,當時以爲頗有用一直收藏着。
曾經有一段時間發現.NET的字符串前綴轉義標識@支持換行,參考下面的代碼例子,@符號支持多行文本。
private string test = @" [assembly: AssemblyCopyright(Copyright © 2015)]
[assembly: AssemblyTrademark()]
[assembly: AssemblyCulture()]";
使用Microsoft.VisualBasic程序集中的方法,一步代碼調用實現簡體轉化爲繁體,參考下面的方法代碼。
public string Convert(string s)
{
return (Microsoft.VisualBasic.Strings.StrConv(s as string, Microsoft.VisualBasic.VbStrConv.TraditionalChinese, 0));
}
凡是WinForms程序,應該在你的程度開頭增長下面的幾行代碼以實現異常處理,將系統拋出的異常轉化給當前程序處理,並提供友好的界面顯示異常。
CustomExceptionHandler eh = new CustomExceptionHandler();
Application.ThreadException += new ThreadExceptionEventHandler(eh.OnThreadException);
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Management Studio源代碼下載:http://files.cnblogs.com/files/JamesLi2015/ManagementStudio.zip