如果我在字符串中有一些文本,我如何将其复制到剪贴板,以便用户可以将其粘贴到另一个窗口(例如,从我的应用程序到记事本)?
System.Windows.Clipboard (PresentationCore.dll)
Winforms: System.Windows.Forms.Clipboard
两者都有一个静态的SetText方法。
System.Windows.Forms.Clipboard.SetText (Windows窗体)或System.Windows.Clipboard.SetText (WPF)
I wish calling SetText were that easy but there are quite a few gotchas that you have to deal with. You have to make sure that the thread you are calling it on is running in the STA. It can sometimes fail with an access denied error then work seconds later without problem - something to do with the COM timing issues in the clipboard. And if your application is accessed over Remote Desktop access to the clipboard is sketchy. We use a centralized method to handle all theses scenarios instead of calling SetText directly.
以下是我们的集中代码:
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();
}
然后我们有一个特定的类来设置剪贴板上的文本。在某些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();
在Windows窗体中,如果你的字符串在文本框中,你可以很容易地使用这个:
textBoxcsharp.SelectAll();
textBoxcsharp.Copy();
textBoxcsharp.DeselectAll();
使用这个问题中显示的解决方案System.Windows.Forms.Clipboard.SetText(…),会导致异常:
在OLE调用之前,当前线程必须设置为单线程公寓(STA)模式
为了防止这种情况,你可以添加属性:
[STAThread]
to
static void Main(string[] args)
这对我来说很管用:
你想做的是:
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()之后,字符串被复制到剪贴板中,因此您可以使用Paste或Ctrl + V并将字符串作为string返回,以复制到剪贴板中。
使用try-catch,即使它有错误,它仍然会复制。
Try
Clipboard.SetText("copy me to clipboard")
Catch ex As Exception
End Try
如果使用消息框捕获异常,它将显示错误,但值仍然复制到剪贴板。
推荐文章
- 在c#中从URI字符串获取文件名
- 检查SqlDataReader对象中的列名
- 如何将类标记为已弃用?
- c# 8支持。net框架吗?
- Linq-to-Entities Join vs GroupJoin
- 为什么字符串类型的默认值是null而不是空字符串?
- 在list中获取不同值的列表
- 组合框:向项目添加文本和值(无绑定源)
- AutoMapper:“忽略剩下的?”
- 如何为ASP.net/C#应用程序配置文件值中的值添加&号
- 从System.Drawing.Bitmap中加载WPF BitmapImage
- 如何找出一个文件存在于c# / .NET?
- 为什么更快地检查字典是否包含键,而不是捕捉异常,以防它不?
- [DataContract]的命名空间
- string. isnullorempty (string) vs. string. isnullowhitespace (string)