首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> .NET 實例教學

C# WinForms 開發 33 個實用技巧大全:DataGrid、資料庫、UI、Excel、部署與進階技巧

     編輯:.NET 實例教學

DataGrid / DataGridView 篇

1. 自訂欄標題

var style = new DataGridTableStyle { MappingName = "MyTable" };
var col = new DataGridTextBoxColumn { 
    MappingName = "title_id", 
    HeaderText = "標題 ID" 
};
style.GridColumnStyles.Add(col);
dataGrid1.TableStyles.Add(style);

2. 篩選 Null 值

// SQL
WHERE column_name IS NULL

// DataTable.Select
var rows = dt.Select("ColumnName IS NULL");

3. 只顯示日期不顯示時間

// SQL Server
SELECT CONVERT(varchar(10), DateCol, 120) AS DateOnly -- yyyy-MM-dd
// 或
SELECT CAST(DateCol AS DATE) AS DateOnly

// DataGrid 欄位格式化
dataGridView1.Columns["DateCol"].DefaultCellStyle.Format = "yyyy-MM-dd";

4. 合併兩欄顯示

// SQL
SELECT col1 + col2 AS Merged FROM Table -- SQL Server
SELECT col1 || col2 AS Merged FROM Table -- Oracle

// DataTable Expression
var dc = new DataColumn("FullName", typeof(string)) { 
    Expression = "FirstName + ' ' + LastName" 
};
dt.Columns.Add(dc);

5. 匯出 Excel 完整範本 (含樣式、分頁、頁碼)

private void ExportToExcel(DataTable dt) {
    var excel = new Microsoft.Office.Interop.Excel.Application();
    excel.Workbooks.Add(true);
    var ws = (Worksheet)excel.ActiveSheet;

    // 標題列
    for (int c = 0; c < dt.Columns.Count; c++)
        ws.Cells[1, c + 1] = dt.Columns[c].ColumnName;

    // 資料列
    for (int r = 0; r < dt.Rows.Count; r++)
        for (int c = 0; c < dt.Columns.Count; c++)
            ws.Cells[r + 2, c + 1] = dt.Rows[r][c];

    // 邊框
    var range = ws.Range[ws.Cells[1, 1], ws.Cells[dt.Rows.Count + 1, dt.Columns.Count]];
    range.Borders.LineStyle = XlLineStyle.xlContinuous;
    range.Borders.Weight = XlBorderWeight.xlThin;

    // 標題列凍結、置中
    ws.Rows[1].HorizontalAlignment = XlHAlign.xlHAlignCenter;
    ws.PageSetup.PrintTitleRows = "$1:$1";
    ws.PageSetup.CenterFooter = "第 &P 頁 / 共 &N 頁";

    // 數字格式保留前導零
    ws.Columns["A"].NumberFormat = "0000";

    excel.Visible = true;
}

6. 進度顯示需呼叫 DoEvents

for (int i = 0; i < count; i++) {
    // ... 匯出邏輯
    dataGrid1.CaptionText = $"匯出中:{i+1}/{count}";
    Application.DoEvents(); // 讓 UI 重繪
}

資料庫操作篇

7. LIKE 參數化查詢

// SQL Server
SELECT * FROM Table WHERE Column LIKE '%' + @Keyword + '%'

// C# 參數
cmd.Parameters.AddWithValue("@Keyword", keyword);

8. Oracle 取首字母 A-Z

SELECT * FROM Table 
WHERE ASCII(SUBSTR(Column, 1, 1)) BETWEEN ASCII('A') AND ASCII('Z')

9. ExecuteScalar 安全轉型

// 錯誤:(int)cmd.ExecuteScalar() 可能為 DBNull
int id = Convert.ToInt32(cmd.ExecuteScalar()); // 安全處理 DBNull

10. 取得目前日期時間

// C#
DateTime.Now

// SQL Server
GETDATE()

// Oracle
SYSDATE

UI 控制項技巧篇

11. TextBox 接收 Enter 鍵

// 方式 1:表單 AcceptButton
this.AcceptButton = btnOK;

// 方式 2:KeyPress 事件
private void txt_KeyPress(object sender, KeyPressEventArgs e) {
    if (e.KeyChar == (char)Keys.Enter) {
        e.Handled = true; // 避免嗶聲
        btnOK.PerformClick();
    }
}

12. ComboBox 僅能選不能輸入

comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;

13. 按鍵映射:+ → A

private void txt_KeyPress(object sender, KeyPressEventArgs e) {
    if (e.KeyChar == '+') {
        SendKeys.Send("A");
        e.Handled = true;
    }
}

14. Form 啟動最大化

this.WindowState = FormWindowState.Maximized;

15. DataGrid 滾動失焦修正

this.dataGrid1.MouseWheel += (s, e) => this.dataGrid1.Select();

16. 程式化控制 DataGrid 捲動

dataGrid1.Select();
SendKeys.Send("{PGUP}");   // 上一頁
SendKeys.Send("{PGDN}");   // 下一頁
SendKeys.Send("^{LEFT}");  // Ctrl+左
SendKeys.Send("^{RIGHT}"); // Ctrl+右

父子表綁定篇

17. 兩個 DataGrid 顯示 Master-Detail

dataGrid1.DataSource = ds; dataGrid1.DataMember = "ParentTable";
dataGrid2.DataSource = ds; dataGrid2.DataMember = "ParentTable.RelationName";

18. TreeView 顯示多層關係

foreach (DataRow dr1 in ds.Tables["A1"].Rows) {
    var n1 = treeView1.Nodes.Add(dr1["Name"].ToString());
    foreach (DataRow dr2 in dr1.GetChildRows("A1A2")) {
        var n2 = n1.Nodes.Add(dr2["Name"].ToString());
        foreach (DataRow dr3 in dr2.GetChildRows("A2A3"))
            n2.Nodes.Add(dr3["Name"].ToString());
    }
}

表單間傳值篇

19. 委派回呼模式

// Form2
public delegate void SendDataHandler(string data);
public event SendDataHandler DataSent;

private void btnOK_Click(object sender, EventArgs e) {
    DataSent?.Invoke(txtInput.Text);
    this.Close();
}

// Form1
var f2 = new Form2();
f2.DataSent += data => txtResult.Text = data;
f2.ShowDialog();

組件版本與部署篇

20. 自動版本號

// AssemblyInfo.cs
[assembly: AssemblyVersion("1.0.*")] // 建置日期/時間編碼

21. 建立強簽名共用組件 (GAC)

sn -k key.snk
// AssemblyInfo.cs
[assembly: AssemblyKeyFile("key.snk")]
// 建置後
gacutil /i MyLib.dll

22. 取得執行中組件版本

var ver = System.Diagnostics.FileVersionInfo
    .GetVersionInfo(System.Reflection.Assembly.GetExecutingAssembly().Location)
    .FileVersion;

23. 簡易安裝專案 (Setup Project)

  1. 新增「安裝精靈」專案
  2. 選擇「主輸出」
  3. 建置產生 Setup.exe、.msi

24. 安裝時自動建立資料庫

[RunInstaller(true)]
public class DbInstaller : Installer {
    public override void Install(IDictionary stateSaver) {
        base.Install(stateSaver);
        ExecuteSql("master", "CREATE DATABASE MyDB");
        ExecuteSql("MyDB", GetEmbeddedSql("CreateTables.sql"));
    }
    // 將 .sql 設為 Embedded Resource 並用 GetManifestResourceStream 讀取
}

進階技巧篇

25. Flash 呼叫外部 .exe

// Flash ActionScript
fscommand("exec", "App.exe");
// 需發布為 .exe,並在同目錄下建 fscommand 資料夾放 App.exe

26. 刪除 Windows 服務

// CMD
sc delete "ServiceName"

// 或 註冊表
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ServiceName

27. VSS 綁定修復

  1. 斷網 → 開啟專案 → 永久中斷原始碼控制
  2. 刪除所有 .vssscc, .vspscc 檔案
  3. 重新「加入原始碼控制」,工具選項選「不含 Internet」的外掛

28. 序列化物件存入 Access (XML 欄位)

public static string SerializeToXml(object obj) {
    using var sw = new StringWriter();
    new XmlSerializer(obj.GetType()).Serialize(sw, obj);
    return sw.ToString();
}
// 存入 Access Memo/LongText 欄位

29. IEnumerable/IEnumerator 實作要點

  • 實作 IEnumerable 回傳 IEnumerator
  • 值類型避免裝箱:提供強型別 GetEnumerator()、MoveNext()、Current
  • foreach 只需 GetEnumerator() + MoveNext() + Current

30. 類別繼承錯誤:No overload takes 0 arguments

  • 父類別無無參數建構子 → 子類別建構子需 base(...) 傳參
  • 父類別為 sealed → 無法繼承

31. PowerShell New-Alias 快速參考

New-Alias -Name "list" -Value "Get-ChildItem"
New-Alias -Name "w" -Value "Get-WmiObject" -Description "WMI 別名" -Option ReadOnly

32. 鍵盤快捷鍵觸發 Server 控制項

<body onkeydown="if(event.keyCode==38) __doPostBack('ImageButton1','')">
// 需頁面有 LinkButton 等產生 __doPostBack,否則手動註冊

33. null vs String.Empty

表示式意義記憶體
null無參考,未指向任何物件無物件
""空字串物件新物件 (但會被暫存池優化)
string.Empty空字串單例共用靜態實例
// .NET 2.0+ 推薦
if (string.IsNullOrEmpty(s)) { ... }
if (string.IsNullOrWhiteSpace(s)) { ... }

總結

這 33 個技巧涵蓋 WinForms 開發最常見場景:資料呈現、資料庫存取、UI 互動、匯出報表、部署安裝、跨技術整合。建議將常用片段整理成個人程式碼片段庫 (Snippets),並搭配單元測試驗證邊界條件,提升開發效率與程式碼品質。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved