Если у меня есть текст в String, как я могу скопировать его в буфер обмена, чтобы пользователь мог вставить его в другое окно (например, из моего приложения в блокнот)?
Как скопировать содержимое строки в буфер обмена на С#?
Ответ 1
Вы можете использовать System.Windows.Forms.Clipboard.SetText(...)
.
Ответ 2
System.Windows.Forms.Clipboard.SetText
(Winforms) или System.Windows.Clipboard.SetText
(WPF)
Ответ 3
Я хочу, чтобы вызов SetText
был таким простым, но есть немало проблем, с которыми вам приходится иметь дело. Вы должны убедиться, что поток, который вы вызываете, включен в STA. Иногда это может быть неудачно с ошибкой отказа в доступе, а затем работать через несколько секунд без проблем - что-то связанное с проблемами синхронизации времени в буфере обмена. И если ваше приложение доступно через доступ к удаленному рабочему столу, доступ к буфере обмена является отрывочным. Мы используем централизованный метод для обработки всех этих сценариев вместо прямого вызова 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();
Ответ 4
WPF: System.Windows.Clipboard
(PresentationCore.dll)
Winforms: System.Windows.Forms.Clipboard
Оба имеют статический метод SetText
.
Ответ 5
Это работает для меня:
Вы хотите сделать:
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 для копирования в буфер обмена.
Ответ 6
Используя решение, указанное в этом вопросе, System.Windows.Forms.Clipboard.SetText(...)
, приводит к исключению:
Текущий поток должен быть установлен в режим однопоточной квартиры (STA) до того, как вызовы OLE могут быть сделаны
Чтобы предотвратить это, вы можете добавить атрибут:
[STAThread]
к
static void Main(string[] args)
Ответ 7
В Windows Forms, если ваша строка находится в текстовом поле, вы можете легко использовать это:
textBoxcsharp.SelectAll();
textBoxcsharp.Copy();
textBoxcsharp.DeselectAll();
Ответ 8
Clipboard.SetText
- это то, что вы хотите.
Ответ 9
Используйте try
- catch
, даже если он имеет ошибку, он все равно будет скопирован.
Try
Clipboard.SetText("copy me to clipboard")
Catch ex As Exception
End Try
Если вы используете окно сообщения для получения исключения, оно покажет вам ошибку, но значение все равно будет скопировано в буфер обмена.