Если у меня есть текст в строке, как я могу скопировать его в буфер обмена, чтобы пользователь мог вставить его в другое окно (например, из моего приложения в Блокнот)?
Как скопировать содержимое строки в буфер обмена в C #?
Ответы (8)
Вы можете использовать System.Windows.Forms.Clipboard.SetText(...)
.
System.Windows.Forms.Clipboard.SetText
(Windows Forms) или _ 2_ (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. Я не помню точных сценариев сейчас, и это может не потребоваться в .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 );
}
}
Использование выглядит так:
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 и вернуть строку как String для копирования в буфер обмена .
Использование решения, показанного в этом вопросе, System.Windows.Forms.Clipboard.SetText(...)
, приводит к исключению:
Текущий поток должен быть установлен в режим однопоточного подразделения (STA), прежде чем можно будет выполнять вызовы OLE.
Чтобы этого не произошло, можно добавить атрибут:
[STAThread]
to
static void Main(string[] args)
В Windows Forms, если ваша строка находится в текстовом поле, вы можете легко использовать это:
textBoxcsharp.SelectAll();
textBoxcsharp.Copy();
textBoxcsharp.DeselectAll();
textBox1.Copy();
- person Dozer789; 16.02.2014
Используйте _1 _-_ 2_, даже если у него есть ошибка, он все равно скопирует.
Try
Clipboard.SetText("copy me to clipboard")
Catch ex As Exception
End Try
Если вы используете окно сообщения для захвата исключения, оно покажет вам ошибку, но значение все равно будет скопировано в буфер обмена.