Skip to content

Conversation

adegeo
Copy link
Contributor

@adegeo adegeo commented Sep 26, 2025

Summary

  • Design a plan to document these changes.
  • Write a new article to help people migrate.
  • Migrate code to external files.
  • Add VB code.
  • Update existing articles that reference the clipboard or dataobject.
  • Remove the committed plan files.

Fixes #2113

Internal previews


Internal previews

Toggle expand/collapse
📄 File 🔗 Preview link
.github/copilot-instructions.md .github/copilot-instructions
.github/instructions/Snippets.Migrate.instructions.md .github/instructions/Snippets.Migrate.instructions
.github/instructions/Snippets.Push.instructions.md .github/instructions/Snippets.Push.instructions
.github/instructions/Snippets.Upgrade.instructions.md .github/instructions/Snippets.Upgrade.instructions
.github/projects/article-templates/template-whats-new.md .github/projects/article-templates/template-whats-new
.github/prompts/Editing.FullPass.prompt.md .github/prompts/Editing.FullPass.prompt
.github/prompts/RefreshLinks.prompt.md .github/prompts/RefreshLinks.prompt
.github/prompts/ValidateTemplate.prompt.md .github/prompts/ValidateTemplate.prompt
AGENTS.md AGENTS
dotnet-desktop-guide/winforms/advanced/drag-and-drop-operations-and-clipboard-support.md dotnet-desktop-guide/winforms/advanced/drag-and-drop-operations-and-clipboard-support
dotnet-desktop-guide/winforms/advanced/how-to-add-data-to-the-clipboard.md dotnet-desktop-guide/winforms/advanced/how-to-add-data-to-the-clipboard
dotnet-desktop-guide/winforms/advanced/how-to-enable-binaryformatter-clipboard-support.md dotnet-desktop-guide/winforms/advanced/how-to-enable-binaryformatter-clipboard-support
dotnet-desktop-guide/winforms/advanced/how-to-retrieve-data-from-the-clipboard.md dotnet-desktop-guide/winforms/advanced/how-to-retrieve-data-from-the-clipboard
dotnet-desktop-guide/winforms/migration/clipboard-dataobject-net10.md dotnet-desktop-guide/winforms/migration/clipboard-dataobject-net10

@adegeo adegeo requested a review from JeremyKuhne October 3, 2025 01:55
@adegeo adegeo marked this pull request as ready for review October 3, 2025 02:01
Copy link
Member

@JeremyKuhne JeremyKuhne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A number of the samples aren't right. I've commented on some of them. They should be validated. I didn't go through all of them exhaustively, I'll look again after you've updated again and validated that your samples work.

{
public class BinaryFormatterSupport
{
public class Person
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BinaryFormatter serialization requires [Serializable].

// Explicit allow-list of permitted types—add only what you need
var allowedTypes = new Dictionary<string, Type>
{
["MyApp.Person"] = typeof(Person),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These type names don't match the real type names.

namespace ClipboardExamples
{
// <ITypedDataObjectImplementation>
public class TypedDataObject : DataObject, ITypedDataObject
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DataObject implements ITypedDataObject so this isn't a good example. I don't think writing samples for ITypedDataObject is worth pre-emptively doing.

public static void ModernTryGetDataExample()
{
// Use this - type-safe approach with TryGetData<T>()
if (Clipboard.TryGetData("MyApp.Person", out Person person))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code isn't particularly helpful without the set/get loop. The true modern way would be to SetDataAsJson then TryGetData.


public static void BrokenCustomTypeExample()
{
// This worked in .NET 8 and earlier but silently fails starting with .NET 9
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should see a first chance exception under the debugger. The failure happens when OLE tries to make a copy of the data because of the default is copy = true on SetData. If it is set to false it will just work in process as we don't actually have to serialize the type.

// Later retrieval with type safety
if (Clipboard.TryGetData("MyInt", out int value))
{
ProcessInteger(value);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe having the Console.WriteLine inline would be clearer?

Clipboard.SetData("MyTimeSpan", TimeSpan.FromMinutes(30));

// Later retrieval with type safety
if (Clipboard.TryGetData("MyInt", out int value))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won't work. The clipboard only has a single item, which would be "MyTimeSpan" in this case.


`BinaryFormatter` was removed from the runtime in .NET 9 because of security vulnerabilities. This change broke clipboard and drag-and-drop operations with custom objects. .NET 10 introduces new APIs that use JSON serialization and type-safe methods to restore this functionality, improve security, and provide better error handling and cross-process compatibility.

One significant change is that <xref:System.Windows.Clipboard.SetData(System.String,System.Object)?displayProperty=nameWithType> no longer works with custom types. It silently fails without storing data on the clipboard. <xref:System.Windows.Forms.Clipboard.GetData(System.String)?displayProperty=nameWithType> is obsolete in .NET&nbsp;10 and shouldn't be used, even for built-in types. Use the new <xref:System.Windows.Forms.Clipboard.TryGetData*?displayProperty=nameWithType> and <xref:System.Windows.Forms.Clipboard.SetDataAsJson``1(System.String,``0)?displayProperty=nameWithType> methods for type-safe operations and JSON serialization of custom objects.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No longer works "by default".

To see the failure, you have to catch first chance exceptions under the debugger to see it fail on OLE trying to retrieve a copy of the data (which happens when you set if copy == true, the default, otherwise on get).

:::code language="json" source="./snippets/how-to-enable-binaryformatter-clipboard-support/csharp/runtimeconfig.json":::

> [!IMPORTANT]
> Without this specific runtime switch, clipboard operations won't fall back to `BinaryFormatter` even if general serialization support is enabled. This switch is required specifically for Windows Forms clipboard functionality.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same procedures and switch are used for WPF. If you happen to have both WPF and WinForms in the same project, both Clipboard classes will be enabled.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

WinForms: Clipboard/Data Serialization changes
2 participants