web-dev-qa-db-fra.com

Comment copier le contenu d'une chaîne dans le Presse-papiers en C #?

Si j'ai du texte dans une chaîne, comment puis-je le copier dans le presse-papiers afin que l'utilisateur puisse le coller dans une autre fenêtre (par exemple, depuis mon application vers le Bloc-notes)?

253
Elie

Vous pouvez utiliser System.Windows.Forms.Clipboard.SetText(...).

317
ravuya
131
Jeff Moser

Je souhaiterais que les appels SetText soient aussi simples que d’habitude, mais vous devez faire face à plusieurs pièges. Vous devez vous assurer que le thread sur lequel vous l'appelez est en cours d'exécution dans la STA. Il peut parfois échouer avec une erreur d'accès refusé puis travailler quelques secondes plus tard sans problème - quelque chose à voir avec les problèmes de minutage COM dans le Presse-papiers. Et si votre application est accessible via Remote Desktop, l'accès au Presse-papiers est superficiel. Nous utilisons une méthode centralisée pour gérer tous ces scénarios au lieu d'appeler directement SetText.

@Stecy: Voici notre code centralisé:

La classe StaHelper exécute simplement du code arbitraire sur un thread de la section Single Thread Apartment (STA) - requis par le Presse-papiers.

abstract class StaHelper
{
    readonly ManualResetEvent _complete = new ManualResetEvent( false );    

    public void Go()
    {
        var thread = new Thread( new ThreadStart( DoWork ) )
        {
            IsBackground = true,
        }
        thread.SetApartmentState( ApartmentState.STA );
        thread.Start();
    }

    // Thread entry method
    private void DoWork()
    {
        try
        {
            _complete.Reset();
            Work();
        }
        catch( Exception ex )
        {
            if( DontRetryWorkOnFailed )
                throw;
            else
            {
                try
                {
                    Thread.Sleep( 1000 );
                    Work();
                }
                catch
                {
                    // ex from first exception
                    LogAndShowMessage( ex );
                }
            }
        }
        finally
        {
            _complete.Set();
        }
    }

    public bool DontRetryWorkOnFailed{ get; set; }

    // Implemented in base class to do actual work.
    protected abstract void Work();
}

Ensuite, nous avons une classe spécifique pour définir du texte dans le presse-papiers. La création manuelle de DataObject est requise dans certains cas Edge sur certaines versions de Windows/.NET. Je ne me souviens pas des scénarios exacts à présent et cela ne sera peut-être pas nécessaire dans .NET 3.5.

class SetClipboardHelper : StaHelper
{
    readonly string _format;
    readonly object _data;

    public SetClipboardHelper( string format, object data )
    {
        _format = format;
        _data = data;
    }

    protected override void Work()
    {
        var obj = new System.Windows.Forms.DataObject(
            _format,
            _data
        );

        Clipboard.SetDataObject( obj, true );
    }
}

L'utilisation ressemble à ceci:

new SetClipboardHelper( DataFormats.Text, "See, I'm on the clipboard" ).Go();
64
Paul Alexander

WPF: System.Windows.Clipboard (PresentationCore.dll)

Winforms: System.Windows.Forms.Clipboard

Les deux ont une méthode statique SetText.

22
bsneeze

Cela fonctionne pour moi:

Vous voulez faire:

System.Windows.Forms.Clipboard.SetText("String to be copied to Clipboard");

Mais cela provoque une erreur en disant que ce doit être dans un seul thread de ApartmentState.STA.

Faisons-le donc dans un tel fil. Le code pour cela:

public void somethingToRunInThread()
{
    System.Windows.Forms.Clipboard.SetText("String to be copied to Clipboard");
}

protected void copy_to_clipboard()
{
    Thread clipboardThread = new Thread(somethingToRunInThread);
    clipboardThread.SetApartmentState(ApartmentState.STA);
    clipboardThread.IsBackground = false;
    clipboardThread.Start();
}

Après avoir appelé copy_to_clipboard(), la chaîne est copiée dans le presse-papiers, vous pouvez donc coller ou Ctrl + V et récupère la chaîne en tant que Chaîne à copier dans le presse-papiers.

16
benli1212

L'utilisation de la solution présentée dans cette question, System.Windows.Forms.Clipboard.SetText(...), entraîne l'exception:

Le thread actuel doit être défini sur le mode STA (Single Thread Apartment) pour que OLE appels puisse être effectué.

Pour empêcher cela, vous pouvez ajouter l'attribut:

[STAThread]

à

static void Main(string[] args)
14
Leroy

Dans Windows Forms, si votre chaîne est dans une zone de texte, vous pouvez facilement utiliser ceci:

textBoxcsharp.SelectAll();
textBoxcsharp.Copy();
textBoxcsharp.DeselectAll();
7
Magnetic_dud