这真的很烦人。我将标签用作列表项用户控件的一部分,用户可以在其中单击它以选择列表项并双击它以重命名它。但是,如果剪贴板中有名称,双击标签会将其替换为标签的文本!
我还检查了应用程序中的其他标签,它们也会在双击时复制到剪贴板。我没有在这个程序中编写任何剪贴板代码,我使用的是标准的 .NET 标签。
有什么办法可以禁用这个功能吗?
我能够使用给出的其他答案的组合来做到这一点。尝试创建这个派生类并用它替换您希望禁用剪贴板功能的任何标签:
Public Class LabelWithOptionalCopyTextOnDoubleClick
Inherits Label
Private Const WM_LBUTTONDCLICK As Integer = &H203
Private clipboardText As String
<DefaultValue(False)> _
<Description("Overrides default behavior of Label to copy label text to clipboard on double click")> _
Public Property CopyTextOnDoubleClick As Boolean
Protected Overrides Sub OnDoubleClick(e As System.EventArgs)
If Not String.IsNullOrEmpty(clipboardText) Then Clipboard.SetData(DataFormats.Text, clipboardText)
clipboardText = Nothing
MyBase.OnDoubleClick(e)
End Sub
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If Not CopyTextOnDoubleClick Then
If m.Msg = WM_LBUTTONDCLICK Then
Dim d As IDataObject = Clipboard.GetDataObject()
If d.GetDataPresent(DataFormats.Text) Then
clipboardText = d.GetData(DataFormats.Text)
End If
End If
End If
MyBase.WndProc(m)
End Sub
End Class
当内部文本值为空时,双击标签而不是尝试将文本值复制到剪贴板。这种方法比我认为的其他方法更清洁:
using System;
using System.Windows.Forms;
public class LabelNoCopy : Label
{
private string text;
public override string Text
{
get
{
return text;
}
set
{
if (value == null)
{
value = "";
}
if (text != value)
{
text = value;
Refresh();
OnTextChanged(EventArgs.Empty);
}
}
}
}
我找到了这篇文章。最后一个poster好像是微软给的解决方案,虽然不是很完美
TKTS 解决方案转换为 C#
初学者: (添加新类,构建,转到设计器并从工具箱拖放名为“LabelWithOptionalCopyTextOnDoubleClick”的位置)
using System.ComponentModel;
using System.Windows.Forms;
using System;
public class LabelWithOptionalCopyTextOnDoubleClick : Label
{
private const int WM_LBUTTONDCLICK = 0x203;
private string clipboardText;
[DefaultValue(false)]
[Description("Overrides default behavior of Label to copy label text to clipboard on double click")]
public bool CopyTextOnDoubleClick { get; set; }
protected override void OnDoubleClick(EventArgs e)
{
if (!string.IsNullOrEmpty(clipboardText))
Clipboard.SetData(DataFormats.Text, clipboardText);
clipboardText = null;
base.OnDoubleClick(e);
}
protected override void WndProc(ref Message m)
{
if (!CopyTextOnDoubleClick)
{
if (m.Msg == WM_LBUTTONDCLICK)
{
IDataObject d = Clipboard.GetDataObject();
if (d.GetDataPresent(DataFormats.Text))
clipboardText = (string)d.GetData(DataFormats.Text);
}
}
base.WndProc(ref m);
}
}
我的解决方案(非常丑陋,但似乎有效)是通过单击将剪贴板文本复制到局部变量,如果剪贴板与局部变量不同,则双击将其恢复。显然,双击的前奏是第一次单击,这就是它起作用的原因。
我要给这个问题加注星标,因为我喜欢更简洁的方法!
我尝试了上面发布的解决方案,但它们对我不起作用。 =(按照这个基本想法,虽然(感谢上面),我来到这里,这似乎工作(也更干净一点)。(在 Windows Server 2012 R2 上运行)
public class MyLabel : System.Windows.Forms.Label
{
private const int WM_LBUTTONDBLCLK = 0x203;
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_LBUTTONDBLCLK)
{
string sSaved = Clipboard.GetText();
System.Drawing.Image iSaved = Clipboard.GetImage();
base.WndProc(ref m);
if (iSaved != null) Clipboard.SetImage(iSaved);
if (!string.IsNullOrEmpty(sSaved)) Clipboard.SetText(sSaved);
}
else
{
base.WndProc(ref m);
}
}
}
必须投入一些额外的努力来保存复制的 Excel 字段等内容,尽管原理是相同的。如前所述,您可以遍历所有可用格式(或您关心的格式)的剪贴板,并将这些值填充到一个 Dictionary 对象中,然后在后面恢复它们。在这种情况下,文字和图片为我涵盖了它。
关于此主题的一个值得(和警示)的链接在这里: 如何在 C# 中备份和恢复系统剪贴板?