winforms 有没有什么方法可以禁用.NET标签的“双击复制”功能?

xt0899hw  于 2023-05-18  发布在  .NET
关注(0)|答案(6)|浏览(198)

这真的很烦人。我将标签用作列表项用户控件的一部分,用户可以单击它以选择列表项,然后双击它以重命名它。但是,如果剪贴板中有一个名称,双击标签将替换为标签的文本!
我还检查了应用程序中的其他标签,它们也会复制到剪贴板上双击。我没有在这个程序中编写任何剪贴板代码,我使用的是标准的.NET标签。
有没有办法禁用此功能?

cqoc49vn

cqoc49vn1#

我能够用给出的其他答案的组合来做到这一点。尝试创建此派生类,并将任何您希望禁用剪贴板功能的标签替换为它:

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
8zzbczxx

8zzbczxx2#

当内部文本值为空时,双击标签,不尝试将文本值复制到剪贴板。这个方法比我认为的其他选择更干净:

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);
            }
        }
    }
}
6jygbczu

6jygbczu3#

找到this post了最后一张海报似乎得到了微软的解决方案,尽管不是一个完美的解决方案。

vfh0ocws

vfh0ocws4#

TKTS解决方案转换为C#
对于初学者:(添加新类、构建、转到设计器并从名为“LabelWithOptialCopyTextOnDoubleClick”的工具箱拖放位置)

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);
    }

}
thtygnil

thtygnil5#

我的解决方案(非常丑陋,但似乎有效)是在单击时将剪贴板文本复制到局部变量,如果剪贴板与局部变量不同,则在双击时将其还原。显然,双击的前兆是第一次单击,这就是为什么它能起作用。
我将在这个问题上加星,因为我喜欢一个更干净的方法!

mcdcgff0

mcdcgff06#

我尝试了上面发布的解决方案,它们不适合我。=(遵循这个基本的想法,虽然(感谢上面),我来到了这里,这似乎工作(有点干净了)。(在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#中备份和还原系统剪贴板?

相关问题