如何从剪贴板检索数据

Clipboard 类提供了可用于与 Windows 操作系统剪贴板功能交互的方法。 许多应用程序使用剪贴板作为数据的临时存储库。 例如,字处理器在剪切和粘贴操作期间使用剪贴板。 剪贴板还可用于将信息从一个应用程序传输到另一个应用程序。

注释

所有基于 Windows 的应用程序共享系统剪贴板。 因此,切换到另一个应用程序时,内容可能会更改。

Clipboard 类只能在设置为单线程单元 (STA) 模式的线程中使用。 若要使用此类,请确保使用 Main 特性标记 STAThreadAttribute 方法。

某些应用程序以多种格式将数据存储在剪贴板上,以增加可能使用该数据的其他应用程序的数量。 剪贴板格式是一种用于标识格式的字符串。 使用标识格式的应用程序可以检索剪贴板上的关联数据。 DataFormats 类提供预定义的格式名称供你使用。 还可以使用自己的格式名称或使用对象的类型作为其格式。 有关将数据添加到剪贴板的信息,请参阅 如何将数据添加到剪贴板

若要确定剪贴板中是否包含某种格式的数据,请使用其中一种格式方法。 若要从剪贴板检索数据,请使用Get方法的一种或TryGetData的方法。

注释

在 .NET Framework 中,应使用 GetData 方法而不是 TryGetData,并且 GetDataObject 方法通常用于多种格式方案。

以单个格式检索

使用 GetAudioStreamGetFileDropListGetImageGetText 方法。 (可选)首先使用相应的 ContainsFormat 方法来确定数据是否以特定格式提供。

对于自定义数据格式,请使用该方法 TryGetData 而不是过时 GetData 的方法。 方法 GetData 在大多数情况下成功返回数据,但如果 BinaryFormatter 是反序列化所需且未启用,它将返回一个指示需要 BinaryFormatterNotSupportedException 实例。 对于自定义数据格式,建议使用基于 JSON 的方法(SetDataAsJson<T>()TryGetData<T>())来提高类型安全性并避免 BinaryFormatter 依赖项。

注释

在 .NET Framework 中,可以使用这些相同的 GetFormat 方法,但对于自定义格式,你需要使用GetData而不是TryGetData

// Demonstrates TryGetData methods for common formats.
// These methods are preferred over the older Get* methods.
public Stream? SwapClipboardAudio(Stream replacementAudioStream)
{
    Stream? returnAudioStream = null;
    if (Clipboard.ContainsAudio())
    {
        returnAudioStream = Clipboard.GetAudioStream();
        Clipboard.SetAudio(replacementAudioStream);
    }
    return returnAudioStream;
}

// Demonstrates TryGetData for file drop lists
public StringCollection? SwapClipboardFileDropList(StringCollection replacementList)
{
    StringCollection? returnList = null;
    if (Clipboard.ContainsFileDropList())
    {
        returnList = Clipboard.GetFileDropList();
        Clipboard.SetFileDropList(replacementList);
    }
    return returnList;
}

// Demonstrates TryGetData for images
public Image? SwapClipboardImage(Image replacementImage)
{
    Image? returnImage = null;
    if (Clipboard.ContainsImage())
    {
        returnImage = Clipboard.GetImage();
        Clipboard.SetImage(replacementImage);
    }
    return returnImage;
}

// Demonstrates TryGetData for text in HTML format
public string? SwapClipboardHtmlText(string replacementHtmlText)
{
    string? returnHtmlText = null;
    if (Clipboard.ContainsText(TextDataFormat.Html))
    {
        returnHtmlText = Clipboard.GetText(TextDataFormat.Html);
        Clipboard.SetText(replacementHtmlText, TextDataFormat.Html);
    }
    return returnHtmlText;
}

// Example of using TryGetData for custom string-based data
public string? GetCustomStringData(string format)
{
    if (Clipboard.TryGetData(format, out object? data))
    {
        return data as string;
    }
    return null;
}
' Demonstrates TryGetData methods for common formats.
' These methods are preferred over the older Get* methods.
Public Function SwapClipboardAudio(ByVal replacementAudioStream As System.IO.Stream) As System.IO.Stream

    Dim returnAudioStream As System.IO.Stream = Nothing

    If Clipboard.ContainsAudio() Then
        returnAudioStream = Clipboard.GetAudioStream()
        Clipboard.SetAudio(replacementAudioStream)
    End If

    Return returnAudioStream

End Function

' Demonstrates TryGetData for file drop lists
Public Function SwapClipboardFileDropList(ByVal replacementList As StringCollection) As StringCollection

    Dim returnList As StringCollection = Nothing

    If Clipboard.ContainsFileDropList() Then
        returnList = Clipboard.GetFileDropList()
        Clipboard.SetFileDropList(replacementList)
    End If

    Return returnList

End Function

' Demonstrates TryGetData for images
Public Function SwapClipboardImage(ByVal replacementImage As Image) As Image

    Dim returnImage As Image = Nothing

    If Clipboard.ContainsImage() Then
        returnImage = Clipboard.GetImage()
        Clipboard.SetImage(replacementImage)
    End If

    Return returnImage

End Function

' Demonstrates TryGetData for text in HTML format
Public Function SwapClipboardHtmlText(ByVal replacementHtmlText As String) As String

    Dim returnHtmlText As String = Nothing

    If Clipboard.ContainsText(TextDataFormat.Html) Then
        returnHtmlText = Clipboard.GetText(TextDataFormat.Html)
        Clipboard.SetText(replacementHtmlText, TextDataFormat.Html)
    End If

    Return returnHtmlText

End Function

' Example of using TryGetData for custom string-based data
Public Function GetCustomStringData(ByVal format As String) As String

    Dim data As Object = Nothing
    If Clipboard.TryGetData(format, data) Then
        Return TryCast(data, String)
    End If

    Return Nothing

End Function

以自定义格式检索

以自定义格式名称使用 TryGetData 方法。 此方法替换现代 .NET 版本中已经过时的GetData方法。

还可以通过此方法使用预定义的格式名称。 有关详细信息,请参阅 DataFormats

重要

在 .NET 10 及更高版本中, SetData 不再适用于序列化所需的 BinaryFormatter 类型。 在大多数情况下,GetData 方法能够成功返回数据,但当反序列化需要 BinaryFormatter 且未启用时,它将返回一个实例 NotSupportedException ,以指示需要 BinaryFormatter 。 下面的示例演示如何检索其他应用程序或早期 .NET 版本可能设置的数据。

注释

在 .NET Framework 中,使用 GetData 方法代替 TryGetData,并且完全支持通过 SetData 进行对象序列化。

// Demonstrates TryGetData using a custom format name and a business object.
// Note: In .NET 10, SetData for objects is no longer supported,
// so this example shows how to retrieve data that might have been
// set by other applications or earlier .NET versions.
public Customer? TestCustomFormat
{
    get
    {
        // For demonstration, we'll use string data instead of objects
        // since SetData for objects is no longer supported in .NET 10
        if (Clipboard.TryGetData("CustomerFormat", out object? data))
        {
            return data as Customer;
        }
        return null;
    }
}
' Demonstrates TryGetData using a custom format name and a business object.
' Note: In .NET 10, SetData for objects is no longer supported,
' so this example shows how to retrieve data that might have been
' set by other applications or earlier .NET versions.
Public ReadOnly Property TestCustomFormat() As Customer
    Get
        Dim data As Object = Nothing
        ' For demonstration, we'll use string data instead of objects
        ' since SetData for objects is no longer supported in .NET 10
        If Clipboard.TryGetData("CustomerFormat", data) Then
            Return TryCast(data, Customer)
        End If
        Return Nothing
    End Get
End Property

Customer在前面的代码片段中使用的类:

[Serializable]
public class Customer
{
    private string nameValue = string.Empty;
    public Customer(string name)
    {
        nameValue = name;
    }
    public string Name
    {
        get { return nameValue; }
        set { nameValue = value; }
    }
}
<Serializable()>
Public Class Customer

    Private nameValue As String = String.Empty

    Public Sub New(ByVal name As String)
        nameValue = name
    End Sub

    Public Property Name() As String
        Get
            Return nameValue
        End Get
        Set(ByVal value As String)
            nameValue = value
        End Set
    End Property

End Class

以多种格式检索

GetDataObject方法用于获取一个IDataObject,然后使用TryGetData来提取特定格式的数据。

对于新式 .NET 应用程序,建议使用此方法,因为它使用较新的、更安全的 API。

注释

在 .NET Framework 中,通常使用 GetDataObject 方法,并直接处理返回的 IDataObject 对象,使用其方法如 GetData,而不是采用较新的 TryGetData 方法。

// Demonstrates how to retrieve data from the Clipboard in multiple formats
// using TryGetData instead of the obsoleted GetData method.
public void TestClipboardMultipleFormats()
{
    IDataObject? dataObject = Clipboard.GetDataObject();
    
    if (dataObject != null)
    {
        // Check for custom format
        if (dataObject.GetDataPresent("CustomFormat"))
        {
            if (Clipboard.TryGetData("CustomFormat", out object? customData))
            {
                if (customData is ListViewItem item)
                {
                    MessageBox.Show(item.Text);
                }
                else if (customData is string stringData)
                {
                    MessageBox.Show(stringData);
                }
            }
        }

        // Check for Customer type - note that object serialization
        // through SetData is no longer supported in .NET 10
        if (dataObject.GetDataPresent(typeof(Customer)))
        {
            if (Clipboard.TryGetData(typeof(Customer).FullName!, out object? customerData))
            {
                if (customerData is Customer customer)
                {
                    MessageBox.Show(customer.Name);
                }
            }
        }

        // For modern .NET 10 applications, prefer using standard formats
        if (Clipboard.ContainsText())
        {
            string text = Clipboard.GetText();
            MessageBox.Show($"Text data: {text}");
        }
    }
}
' Demonstrates how to retrieve data from the Clipboard in multiple formats
' using TryGetData instead of the obsoleted GetData method.
Public Sub TestClipboardMultipleFormats()

    Dim dataObject As IDataObject = Clipboard.GetDataObject()

    If dataObject IsNot Nothing Then

        ' Check for custom format
        If dataObject.GetDataPresent("CustomFormat") Then

            Dim customData As Object = Nothing
            If Clipboard.TryGetData("CustomFormat", customData) Then

                Dim item As ListViewItem = TryCast(customData, ListViewItem)
                If item IsNot Nothing Then
                    MessageBox.Show(item.Text)
                ElseIf TypeOf customData Is String Then
                    MessageBox.Show(CStr(customData))
                End If

            End If

        End If

        ' Check for Customer type - note that object serialization
        ' through SetData is no longer supported in .NET 10
        If dataObject.GetDataPresent(GetType(Customer)) Then

            Dim customerData As Object = Nothing
            If Clipboard.TryGetData(GetType(Customer).FullName, customerData) Then

                Dim customer As Customer = TryCast(customerData, Customer)
                If customer IsNot Nothing Then
                    MessageBox.Show(customer.Name)
                End If

            End If

        End If

        ' For modern .NET 10 applications, prefer using standard formats
        If Clipboard.ContainsText() Then
            Dim text As String = Clipboard.GetText()
            MessageBox.Show($"Text data: {text}")
        End If

    End If

End Sub
[Serializable]
public class Customer
{
    private string nameValue = string.Empty;
    public Customer(string name)
    {
        nameValue = name;
    }
    public string Name
    {
        get { return nameValue; }
        set { nameValue = value; }
    }
}
<Serializable()>
Public Class Customer

    Private nameValue As String = String.Empty

    Public Sub New(ByVal name As String)
        nameValue = name
    End Sub

    Public Property Name() As String
        Get
            Return nameValue
        End Get
        Set(ByVal value As String)
            nameValue = value
        End Set
    End Property

End Class

另请参阅