前兩天開發了個Winform操作Excel和數據庫的一個小程序,把Winform的一些東西又給撿了起來,當中又學到了一些新的東西,特來寫出來留作紀念。
一、CSKIN美化框架的使用
剛開始做的時候,發現Winform的界面是有點丑了,但又不想換成WPF,所以就找到了這個框架,挺好用的,下載一個dll,
引用到項目里就好了。具體步驟:
①在其官網下載壓縮包,http://www.cskin.net/,其內容文件如下。
②在VS的工具箱里新建個組,然后直接把下載中的一個dll文件給拖進去(這里我引用的是CSkin 4.0下的CSkin.dll),
就算引用完成,之后這個組里就會有這個框架里所帶的控件。它的使用方法和winform里的控件都一樣,這一點還是挺方便的。
具體的使用方法見使用教程,里面說的很清楚。,邊一張圖便是美化過后的界面。
二、Aspose.Cells,DataTable,DataGridView的使用。
這次因為有一個功能是顯示Excel的內容到DataGridView上,雖然知道操作Excel有很多方法,但是用着感覺都不是太好。這次找到了一個操作Excel比較好的插件【Aspose.Cells】。聽說是兼容性比較好,什么wps,office 07,13的都沒問題,而且代碼寫得也比較少。 下面是一段Excel導出到DataTable的代碼。

/// <summary>
/// 獲取excel的內容到Datatable /// </summary>
/// <param name="excel"></param>
/// <returns></returns>
public static DataTable GetImportExcelDataTable(string fileName) { Workbook workbook = new Workbook(fileName); Worksheet sheet = workbook.Worksheets[0]; Cells cells = sheet.Cells; //將表中的信息轉到datatable DataTable table = cells.ExportDataTable(1,0,cells.MaxRow,6); return RemoveEmpty( table); } /// <summary>
/// 去除DataTable中整行都是空的數據 /// </summary>
/// <param name="dt"></param>
/// <returns></returns>
public static DataTable RemoveEmpty(DataTable dt) { List<DataRow> removelist = new List<DataRow>(); for (int i = 0; i < dt.Rows.Count; i++) { bool IsNull = true; for (int j = 0; j < dt.Columns.Count; j++) { if (!string.IsNullOrEmpty(dt.Rows[i][j].ToString().Trim())) { IsNull = false; } } if (IsNull) { removelist.Add(dt.Rows[i]); } } for (int i = 0; i < removelist.Count; i++) { dt.Rows.Remove(removelist[i]); } return dt; }
之后,要將datatable里的內容綁定到DataGridView上,我要改變顯示的列名,我去設置DataGridView的上的內容,試了很長時間,也沒成功,最后發現想要改變列名,的設置DataTable上的列名,之后再綁定到DataGridView。
OpenFileDialog file = new OpenFileDialog(); file.Filter = "Excel|*.xls;*.xlsx"; if (file.ShowDialog() == DialogResult.OK) { string excelName = file.FileName; DataTable table = ExcelHelper.GetImportExcelDataTable(excelName); table.Columns[0].ColumnName = "酒店名稱"; table.Columns[1].ColumnName = "酒店編號"; table.Columns[2].ColumnName = "員工姓名"; table.Columns[3].ColumnName = "手機號"; table.Columns[4].ColumnName = "狀態"; table.Columns[5].ColumnName = "郵箱"; dataGridView1.DataSource = table; dataGridView1.Columns[4].FillWeight = 40; //這個是設置列寬的 }
還有一個是給DataGridView設置編號,這個也是有必要的,先找到RowPostPaint這個事件,之后在事件里寫方法,之后DataGridView就能存在編號。
private void dataGridView2_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e) { Rectangle rectangle = new Rectangle(e.RowBounds.Location.X, e.RowBounds.Location.Y, dataGridView1.RowHeadersWidth - 4, e.RowBounds.Height); TextRenderer.DrawText(e.Graphics, (e.RowIndex + 1).ToString(), dataGridView2.RowHeadersDefaultCellStyle.Font, rectangle, dataGridView2.RowHeadersDefaultCellStyle.ForeColor, TextFormatFlags.VerticalCenter | TextFormatFlags.Right); }
三、Winform中全局的異常捕獲處理
因為在程序里會出行一些異常,如用戶的特殊輸入,但是我有不想寫大量try catch語句,所以我就找到了一種方法能夠全局處理異常。找到winfrom的程序入口的文件Program.cs,然后注冊捕獲異常事件,進行處理 ,類似於ASP.NET中Global里的Application_Error。

static class Program { /// <summary>
/// 應用程序的主入口點。 /// </summary>
[STAThread] static void Main() { //處理UI線程異常
Application.ThreadException += Application_ThreadException; //處理未捕獲的異常
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.Automatic); //處理非UI線程異常
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } /// <summary>
/// 處理應用程序域內的未處理異常(非UI線程異常) /// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { try { Exception ex = e.ExceptionObject as Exception; } catch { } } /// <summary>
/// 處理應用程序的未處理異常(UI線程異常) /// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
static void Application_ThreadException(object sender, ThreadExceptionEventArgs e) { try { //MessageBox.Show(e.Exception.Message);
if (e.Exception.Message.Contains("登錄失敗") ||e.Exception.Message.Contains("error: 40")) { MessageBox.Show(@"數據庫遠程登錄失敗,請檢查網絡鏈接"); } else { MessageBox.Show(@"請檢查輸入或文件中是否有特殊字符如:,'< > * ( ) """); } } catch { } } }
在測試的時候剛開始遇到一些疑惑,用VS調試的時候,這段代碼捕獲到異常后,彈出了我設置的提示框,但是程序還是拋異常了,本以為代碼寫錯了,但最后發現,這個不是錯誤。用bin文件夾下的exe文件測試就不會有問題了,打包后還是沒問題了。
四、程序打包(非InstallShield方式)
過了vs2010后,打包感覺好無語,操作步驟真是復雜,還非的下載InstallShield,因為是局域網,不是公網ip,在那個注冊下載那個頁面,國家地區那一列直接就不給機會選擇,換種方式打包了。
打包過程中還發現這種問題,也是搜了好久,這種解決辦法是去掉項目屬性中的簽名,之后便能夠發布成功。
至此,從項目創建到發布都過了一遍,感覺還是怪怪的,好像還有個地方可以優化,就是用多線程,防止頁面假死,先這樣吧,慢慢再優化。
項目發布到碼雲上,地址: http://git.oschina.net/sdadx/MDM
參考文章:1.Winform中的dataGridView添加自動編號
2.(C#)利用Aspose.Cells組件導入導出excel文件
5.CSKIN論壇 http://bbs.cskin.net/