文字列にテキストがある場合、それをクリップボードにコピーして、ユーザーが別のウィンドウに貼り付けることができるようにするにはどうすればよいですか(たとえば、アプリケーションからメモ帳に)。
8 に答える
を使用できますSystem.Windows.Forms.Clipboard.SetText(...)
。
System.Windows.Forms.Clipboard.SetText
(Windowsフォーム)またはSystem.Windows.Clipboard.SetText
(WPF)
電話SetText
がこんなに簡単だったらいいのにと思いますが、対処しなければならない落とし穴がかなりあります。呼び出しているスレッドがSTAで実行されていることを確認する必要があります。アクセス拒否エラーで失敗し、数秒後に問題なく動作する場合があります。これは、クリップボードのCOMタイミングの問題と関係があります。また、リモートデスクトップを介してアプリケーションにアクセスする場合、クリップボードへのアクセスは大雑把です。直接呼び出すのではなく、一元化された方法を使用してこれらすべてのシナリオを処理しSetText
ます。
@Stecy:これが私たちの一元化されたコードです:
StaHelperクラスは、クリップボードに必要なシングルスレッドアパートメント(STA)のスレッドで任意のコードを実行するだけです。
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();
}
次に、クリップボードにテキストを設定するための特定のクラスがあります。DataObject
一部のバージョンのWindows/.NETでは、一部のエッジケースで手動で作成する必要があります。現在、正確なシナリオを思い出せません。.NET3.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 );
}
}
使用法は次のようになります。
new SetClipboardHelper( DataFormats.Text, "See, I'm on the clipboard" ).Go();
WPF:System.Windows.Clipboard
(PresentationCore.dll)
Winforms:System.Windows.Forms.Clipboard
どちらにも静的SetText
メソッドがあります。
これは私のために働きます:
あなたがしたい:
System.Windows.Forms.Clipboard.SetText("String to be copied to Clipboard");
ただし、ApartmentState.STAのシングルスレッドにある必要があるというエラーが発生します。
それでは、そのようなスレッドで実行させましょう。そのためのコード:
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();
}
を呼び出しcopy_to_clipboard()
た後、文字列がクリップボードにコピーされるため、貼り付けまたはCtrl+Vを使用して文字列を文字列として取得し、クリップボードにコピーできます。
この質問で示されたソリューションを使用するSystem.Windows.Forms.Clipboard.SetText(...)
と、例外が発生します。
OLE呼び出しを行う前に、現在のスレッドをシングルスレッドアパートメント(STA)モードに設定する必要があります
これを防ぐために、次の属性を追加できます。
[STAThread]
に
static void Main(string[] args)
Windowsフォームでは、文字列がテキストボックスにある場合、次のように簡単に使用できます。
textBoxcsharp.SelectAll();
textBoxcsharp.Copy();
textBoxcsharp.DeselectAll();
try
-を使用catch
します。エラーが発生した場合でも、コピーされます。
Try
Clipboard.SetText("copy me to clipboard")
Catch ex As Exception
End Try
メッセージボックスを使用して例外をキャプチャすると、エラーが表示されますが、値はクリップボードにコピーされます。