原文:https://docs.microsoft.com/zh-cn/dotnet/api/system.windows.forms.clipboard?view=netcore-3.1
剪貼板是Windows操作系統中最常用的功能之一,它用來從一個應用程序向另一個應用程序傳遞數據,可以是文本,圖象,甚至是程序對象。
不過剪貼板也有限制,它在某個特定的時間只能指向一塊內容,每一個隨后復制的內容都會取代先前的內容。
為了在C#中操作剪貼板(包括內容的讀取和寫入)需要使用到System.Windows.Forms.Clipboard類
一、向剪貼板中存放東西。相當於Ctrl+C
主要用到Clipboard類的SetDataObject(Object obj,bool copy )方法,此方法是將目標對象放入剪貼板中。
obj就是目標對象,
參數copy表示是否在程序結束時仍然保存對象於剪貼板。如果設置為false,或者不設置,將在程序運行結束后不保留剪切板內容。
1、存放普通數據
Clipboard.SetDataObject(textBox1.Text);
通過以上代碼便完成了復制操作。你可以打開文本文檔,按下Ctrl+V 看一下效果。
2、往剪切板里存取自定義數據
C#的對象的數據結構並不能為剪切板所理解,所以你要把你自定義的數據放到剪切板去的話要把它序列化,在實際操作中,是要你提供一個“可序列化”的對象。
注意:
- 對象必須是可序列化的(Serializable注解),才能將其放在剪貼板上。 如果將非序列化對象傳遞到剪貼板方法,則該方法將失敗,且不會引發異常。
- Clipboard 類只能在設置為單線程單元(STA)模式的線程中使用。 若要使用此類,請確保
Main
方法使用 STAThreadAttribute 屬性進行標記。 - 如果數據比較復雜,可以考慮把數據自行序列化到一個Stream對象去,再把Stream對象寫入剪切板,獲取的時候對Stream對象自行反序列化,還原數據。
下面是個簡單的例子:
[Serializable] public class User { public int age { get; set; } public string name { get; set; } } class Program { [STAThread] static void Main(string[] args) { User userIn = new User(); userIn.name = "Jack"; userIn.age = 18; Clipboard.SetData("mydata", userIn); User userOut = (User)Clipboard.GetData("mydata"); Console.WriteLine(userOut.name +" | " + userOut.age); } }
最后要注意的一點是由於這里的數據類型是“mydata”,你也可以指定別的名字,這種類型數據只有你自己的程序能讀懂,也就是說,你是不能打開記事本或者Photoshop,直接把你這個User對象貼上去的。
二、從剪貼板讀取東西。相當於Ctrl+V
主要用到的方法為:GetDataObject()用來檢索剪貼板中的數據,它返回的是任何格式的數據,返回IDataObject接口,用來接收任何數據。
- IDataObject接口實例的 GetDataPresent (Type Format)方法返回bool值,獲取指定類型是否可用。
- 另外就是DataFormats類,該類主要是用來標識格式用的。
- 從剪切板上獲得數據不影響剪貼板的內容,GetData的返回值是存儲在剪貼板上的副本。
1、粘貼文本的方法:
IDataObject iData = Clipboard.GetDataObject(); if (iData.GetDataPresent(DataFormats.Text)) { //如果剪貼板中的數據是文本格式 this.label1.Text = (string)iData.GetData(DataFormats.Text);//檢索與指定格式相關聯的數據 } else { MessageBox.Show("目前剪貼板中數據不可轉換為文本", "錯誤"); }
2、粘貼圖片:
if (Clipboard.ContainsImage()) { Image img = Clipboard.GetImage(); pictureBox1.Image = img; }
或者
IDataObject iData = Clipboard.GetDataObject(); if (iData.GetDataPresent(DataFormats.Bitmap)) { this.pictureBox1.Image = (Bitmap)iData.GetData(DataFormats.Bitmap); } else { MessageBox.Show("目前剪貼板中數據不可轉換為圖片", "錯誤"); }
3、控件自帶的paste方法
另外我們可以利用某些控件自帶的paste方法進行粘貼操作,我們這里以richtextbox為例。[注:在使用控件的paste方法之前必須確保控件的readonly屬性為false,否則無法對控件進行此操作!]
現在我們就用paste方法來實現向richtextbox中加入圖片。
OpenFileDialog fd = new OpenFileDialog(); fd.Filter = "圖片文件|*.jpg|所有文件|*.*"; if (fd.ShowDialog() == DialogResult.OK) { Clipboard.SetDataObject(Image.FromFile(fd.FileName), true); DataFormats.Format myFormat = DataFormats.GetFormat(DataFormats.Bitmap); richTextBox2.ReadOnly = false; if (richTextBox2.CanPaste(myFormat))//判斷此控件是否可以粘貼這個格式的數據 { richTextBox2.Paste(myFormat); } else { MessageBox.Show("無法粘貼!"); } }