在桌面應用開發中,剪貼簿是使用者交換資料的核心通道。無論是截圖工具、文件編輯器,還是跨應用程式拖放功能,都離不開對剪貼簿資料的讀寫與型別識別。本文系統梳理 C# 操作剪貼簿的兩大核心場景——資料型別判斷與資料擷取儲存,並提供可直接落地的完整程式碼範例。
| 類別/介面 | 命名空間 | 核心功能 |
|---|---|---|
Clipboard | System.Windows.Forms | 靜態類別,提供 GetDataObject()、SetDataObject() 等存取方法 |
DataFormats | System.Windows.Forms | 預定義剪貼簿資料格式常數(Text、Bitmap、Html、FileDrop 等 21 種) |
IDataObject | System.Windows.Forms | 資料傳輸介面,提供 GetDataPresent()、GetData() 等型別檢查與擷取方法 |
Clipboard.GetDataObject() 取得 IDataObject 介面實例GetDataPresent(DataFormats.Format) 依優先順序檢查型別true 表示符合或可轉換為指定格式using System;
using System.Windows.Forms;
public class ClipboardTypeDetector
{
public static void Main()
{
IDataObject data = Clipboard.GetDataObject();
if (data.GetDataPresent(DataFormats.Bitmap))
Console.WriteLine("剪貼簿資料型別:位圖");
else if (data.GetDataPresent(DataFormats.Text))
Console.WriteLine("剪貼簿資料型別:純文字");
else if (data.GetDataPresent(DataFormats.Html))
Console.WriteLine("剪貼簿資料型別:HTML 格式");
else if (data.GetDataPresent(DataFormats.FileDrop))
Console.WriteLine("剪貼簿資料型別:檔案清單");
else
Console.WriteLine("剪貼簿資料型別:其他 (" + data.GetDataPresent(DataFormats.UnicodeText) + ")");
}
}
IDataObject.GetData() 回傳 object(參考型別),必須透過強制轉型拆箱為實值型別:
Bitmap bmp = (Bitmap)data.GetData(DataFormats.Bitmap); // 位圖拆箱
string txt = (string)data.GetData(DataFormats.Text); // 字串拆箱
圖 01:偵測到位圖時自動存檔至 C:\my.bmp
圖 02:偵測到文字時載入 RichTextBox 顯示
using System;
using System.Drawing;
using System.Windows.Forms;
public class ClipboardSaverForm : Form
{
private RichTextBox richTextBox1;
private Button btnGetData;
public ClipboardSaverForm()
{
InitializeComponent();
}
private void InitializeComponent()
{
this.richTextBox1 = new RichTextBox { Location = new Point(40, 16), Size = new Size(336, 264) };
this.btnGetData = new Button { Location = new Point(128, 304), Text = "取得剪貼簿資料", Size = new Size(128, 24) };
this.btnGetData.Click += BtnGetData_Click;
this.ClientSize = new Size(408, 357);
this.Controls.AddRange(new Control[] { richTextBox1, btnGetData });
this.Text = "C# 剪貼簿資料擷取與儲存示範";
}
private void BtnGetData_Click(object sender, EventArgs e)
{
IDataObject data = Clipboard.GetDataObject();
if (data.GetDataPresent(DataFormats.Bitmap))
{
Bitmap bmp = (Bitmap)data.GetData(DataFormats.Bitmap);
bmp.Save(@"c:\my.bmp");
MessageBox.Show("已將位圖儲存至 C:\\my.bmp");
}
else if (data.GetDataPresent(DataFormats.Text))
{
string txt = (string)data.GetData(DataFormats.Text);
richTextBox1.Text = txt;
}
else
{
MessageBox.Show("剪貼簿包含非支援格式資料");
}
}
[STAThread]
public static void Main()
{
Application.Run(new ClipboardSaverForm());
}
}
掌握上述基礎後,你可以輕鬆實作:
SendKeys.SendWait("{PRTSC}") 觸發列印螢幕鍵 → 從剪貼簿取得 Bitmap → 裁切 → 儲存AddClipboardFormatListener)→ 即時同步至雲端/其他裝置| 問題 | 原因 | 解決方法 |
|---|---|---|
| 呼叫 Clipboard 方法拋出 ExternalException | 剪貼簿被其他程式佔用 | 加入重試機制(Thread.Sleep + try/catch 迴圈),最多重試 3-5 次 |
| GetDataPresent(Text) 為 true 但 GetData(Text) 回傳 null | 資料為 UnicodeText 非 ANSI Text | 優先檢查 DataFormats.UnicodeText,或使用 GetData(DataFormats.UnicodeText) |
| 非 UI 執行緒存取剪貼簿失效 | Clipboard 類別要求 STA 執行緒 | 確保呼叫端標記 [STAThread],或使用 Task.Run 配合 Dispatcher/Control.Invoke |
C# 操作剪貼簿的核心在於 Clipboard → IDataObject → DataFormats 三角關係。掌握 GetDataPresent 型別檢查與 GetData 拆箱轉換兩大關鍵步驟,即可應對 90% 的剪貼簿應用場景。建議開發者將常用邏輯封裝為靜態工具類 ClipboardHelper,統一處理例外、重試與編碼轉換,提升專案維護性。