.NET C/S(WinForm)开发技巧点滴(转)
花費了十天時間,為公司開發了一套簡單的網絡版的信息管理系統,功能主要有客戶信息管理,員工信息管理,常用信息管理(各種信函打印、常用網址/常用電話等),公司簡單的財務管理等。把一些點點滴滴的技巧在此記錄下來,以備查用。
1.數據綁定。 DataReader 讀取數據,用DataTable.Load(IDataReader)方法將數據加載到 DataTable ,用DataGridView 顯示輸出。不要把DataGridView直接綁定到DataReader的目的是數據導出到Excel時,數據源可以再次從DataGridView獲得。
不要在 DataGridView 內編輯添加數據,因為數據類型檢查不嚴格(或要嚴格檢查類型需要花費更大的成本)。
2.數據導出到 Excel 。代碼如下:
?
/**//**//**////?<summary>///?
///?**?DataTable?數據導出到?Excel?**
///
///??Author:?周振興?(Zxjay?飄遙)
///?
///??E-Mail:?tda7264@163.com
///?
///??Blog:?http://blog.csdn.net/zxjay
///?
///??Date:?07-08-31
///?
///?</summary>
????????????????Excel.Application?app?=?new?Excel.Application();
????????????????app.Visible?=?false;
????????????????Excel.Workbook?wb?=?app.Workbooks.Add(true);
????????????????Excel.Worksheet?ws?=?(Excel.Worksheet)wb.Worksheets.Add(Type.Missing,?Type.Missing,?Type.Missing,?
Type.Missing);
????????????????DataTable?dt?=?(DataTable)dgvClientInfo.DataSource;
????????????????for?(int?i?=?0;?i?<?dt.Columns.Count;?i++)
????????????????{
????????????????????ws.Cells[1,?i?+?1]?=?dt.Columns[i].ColumnName;
????????????????}
????????????????for?(int?j?=?0;?j?<?dt.Rows.Count;?j++)
????????????????{
????????????????????for?(int?k?=?0;?k?<?dt.Columns.Count;?k++)
????????????????????{
????????????????????????ws.Cells[j?+?2,?k?+?1]?=?dt.Rows[j][k];
????????????????????}
????????????????}
????????????????app.Visible?=?true;
注意:Excel的Cells[,]下標是從1,1開始的,而不是0,0。
3.防止子窗口重復打開,確保某一子窗口只打開一次。代碼為:
????????????{
????????????????if?(frm?is?WorkerList)
????????????????{
????????????????????frm.WindowState?=?FormWindowState.Normal;
????????????????????frm.Activate();
????????????????????return;
????????????????}
????????????}
????????????WorkerList?wl?=?new?WorkerList();
????????????wl.MdiParent?=?this;
????????????wl.Show();
4.使用枚舉 enum 區分類同信息。
硬編碼方式容易造成混亂。如本系統的常用電話/常用網址,數據項都為:名稱-內容-備注,可將它們保存在同一個表中,在程序中為區分信息類型,可定義以下枚舉:
?
????public?enum?TelWeb????{
????????Telephone,WebSite
????}
5.在ToolStrip中加入其它WinForm控件。
如在ToolStrip中加入DateTimePicker。如圖:
Code????????????DateTimePicker?dt1?=?new?DateTimePicker();
????????????dt1.Width?=?110;
????????????ToolStripControlHost?host1?=?new?ToolStripControlHost(dt1);
????????????host1.Alignment?=?ToolStripItemAlignment.Right;
????????????toolStrip1.Items.Insert(10,?host1);
6.用微軟的可打印的富文本框控件打印帶格式的文本。
與.NETFX自帶的RichTextBox相比只增強了打印功能。通過該控件,可設置文本字體、顏色、對齊方式、粘貼圖片,可打印看上去很專業的文檔,截圖如下:
參考:http://support.microsoft.com/kb/812425/zh-cn
7.保存富文本格式到數據庫。
以二進制格式保存。保存的代碼為:
????????????MemoryStream?ms?=?new?MemoryStream();????????????rtbContent.SaveFile(ms,?RichTextBoxStreamType.RichText);
????????????byte[]?bt=ms.ToArray();?//將bt保存到數據庫
讀取的代碼為:
????????????MemoryStream?ms?=?new?MemoryStream(bt,?false);
????????????rtbContent.LoadFile(ms,?RichTextBoxStreamType.RichText);
在SQLServer中對應的數據類型為:image
8.管理員權限控制。
管理員信息表中權限字段保存一個字符串,擁有該項權限則在字符串相應位置保存為1,沒有該項權限為0。在管理員登錄時判斷權限,啟用或禁用相應的菜單項。
9.信息分類。
如客戶分類分為:軟件客戶、網站客戶、合作客戶等。如果數據量不是太大,可不用單獨建立分類表,在添加的時候,客戶類型。可用ComboBox,在Form加載時檢索數據庫中已有的客戶類型填充到ComboBox中。這樣可選擇已有客戶類型,也可以添加新的客戶類型。
10.數據庫安裝。
不必集成在安裝包中,可單獨寫一個WinForm程序來收集連接服務器的信息(服務器地址、數據庫名、用戶名、密碼等),并執行數據庫生成的腳本來建立數據表,視圖,存儲過程、索引等。
讀取保存數據庫腳本文件的代碼:
????????{
????????????StreamReader?sr?=?new?StreamReader(fileName);
????????????return?sr.ReadToEnd();
????????}
注意:數據庫生成的腳本必須把"GO"去掉,否則執行時報錯。
11.安全控制。
由于是網絡版系統,因而安全性要考慮周全。數據庫連接字符串加密保存在配置文件中。為了防止軟件XCopy到其它機器中,可以取機器的硬件(如硬盤、網卡、CPU)序列號的一部分再加上自己的私有密鑰作為連接字符串的加密密鑰(八位ASCII),確保密鑰的私密性、每機器唯一性。
(1)取得機器CPU的ID的前八位作為密鑰:
????????public?static?string?GetProcessID()????????{
????????????try
????????????{
????????????????string?str?=?string.Empty;
????????????????ManagementClass?mcCpu?=?new?ManagementClass("win32_Processor");
????????????????ManagementObjectCollection?mocCpu?=?mcCpu.GetInstances();
????????????????foreach?(ManagementObject?m?in?mocCpu)
????????????????{
????????????????????str?=?m["ProcessorId"].ToString().Trim().Substring(0,?8);
????????????????}
????????????????return?str;
????????????}
????????????catch?(Exception?ex)
????????????{
????????????????return?"zhenxing";?//如果失敗取默認的密鑰
????????????}
????????}
?(2)加密算法:
????????public?static?string?Encode(string?data)????????{
????????????byte[]?aKey?=?System.Text.ASCIIEncoding.ASCII.GetBytes(GetProcessID());
????????????byte[]?aIV?=?System.Text.ASCIIEncoding.ASCII.GetBytes(GetProcessID());
????????????DESCryptoServiceProvider?cp?=?new?DESCryptoServiceProvider();
????????????MemoryStream?ms?=?new?MemoryStream();
????????????CryptoStream?cs?=?new?CryptoStream(ms,?cp.CreateEncryptor(aKey,?aIV),?CryptoStreamMode.Write);
????????????StreamWriter?sw?=?new?StreamWriter(cs);
????????????sw.Write(data);
????????????sw.Flush();
????????????cs.FlushFinalBlock();
????????????sw.Flush();
????????????return?Convert.ToBase64String(ms.GetBuffer(),?0,?(int)ms.Length);
????????}
?(3)解密算法:
????????public?static?string?Decode(string?data)????????{
????????????byte[]?aKey?=?System.Text.ASCIIEncoding.ASCII.GetBytes(GetProcessID());
????????????byte[]?aIV?=?System.Text.ASCIIEncoding.ASCII.GetBytes(GetProcessID());
????????????byte[]?Enc;
????????????try
????????????{
????????????????Enc?=?Convert.FromBase64String(data);
????????????}
????????????catch
????????????{
????????????????return?null;
????????????}
????????????DESCryptoServiceProvider?cp?=?new?DESCryptoServiceProvider();
????????????MemoryStream?ms?=?new?MemoryStream(Enc);
????????????CryptoStream?cs?=?new?CryptoStream(ms,?cp.CreateDecryptor(aKey,?aIV),?CryptoStreamMode.Read);
????????????StreamReader?sr?=?new?StreamReader(cs);
????????????return?sr.ReadToEnd();
????????}
?(4)數據庫連接字符串保存到配置文件:
?
????????public?static?void?SaveToConfig(string?connStr)????????{
????????????XmlDocument?doc?=?new?XmlDocument();
????????????string?fn?=?"zxjay.exe.config";
????????????doc.Load(fn);
????????????XmlNodeList?nodes?=?doc.GetElementsByTagName("add");
????????????for?(int?i?=?0;?i?<?nodes.Count;?i++)
????????????{
????????????????XmlAttribute?att?=?nodes[i].Attributes["key"];
????????????????if?(att.Value?==?"SQLConectionString")
????????????????{
????????????????????att?=?nodes[i].Attributes["value"];
????????????????????att.Value?=?connStr;
????????????????????break;
????????????????}
????????????}
????????????doc.Save(fn);
????????}
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/zxjay/archive/2007/08/31/1766329.aspx
轉載于:https://www.cnblogs.com/greatandforever/archive/2009/07/20/1526959.html
總結
以上是生活随笔為你收集整理的.NET C/S(WinForm)开发技巧点滴(转)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SQL Server 2008 阻止保存
- 下一篇: OXite解读(1)----- 概述