开发者

Is there any way to disable the "double-click to copy" functionality of a .NET label?

开发者 https://www.devze.com 2022-12-24 12:33 出处:网络
This is really annoying. I\'m using the label as part of a list item user control, where the user can click it to select the list item and double-click it to rename it. However, if you had a name in t

This is really annoying. I'm using the label as part of a list item user control, where the user can click it to select the list item and double-click it to rename it. However, if you had a name in the clipboard, double-clicking the label will replace it with the text of the label!

I've also check the other labels in the application, and they will als开发者_如何转开发o copy to the clipboard on a doubleclick. I have not written any clipboard code in this program, and I am using the standard .NET labels.

Is there any way to disable this functionality?


I was able to do it using a combination of the other answers given. Try creating this derived class and replace any labels you wish to disable the clipboard functionality with it:

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


When internal text value is empty then double clicking on label not trying to copy text value to clipboard. This method more cleaner than other alternatives I think:

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


I have found this post. The last poster seems to have been given a solution by Microsoft, albeit not a perfect solution.


TKTS solution converted to C#

For beginners: (add new class, build, go to designer and from toolbox drag and drop position named '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);
    }

}


My solution (terribly ugly, but it seems to work) was to copy clipboard text to a local variable on single-click, and restore it on double-click if the clipboard differs from the local variable. Obviously the precursor to a double-click is the first single-click, which is why it works.

I'm going to star this question because I'd love a cleaner method!


I tried the solutions posted above, and they did not work for me. =( Following that basic idea, though (thanks to above), I arrived here, and this seems to work (a little cleaner too). (running on 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);
        }
    }
}

Some extra effort would have to be invested to preserve things like copied Excel fields and the like, although the principle would be the same. As mentioned, you could iterate over the clipboard for all available formats (or the ones you care about), and stuff those values into a Dictionary object, and then restore them afterwords. Text and pics covers it for me, in this case.

One worthwhile (and cautionary) link to see on this subject is here: How do I backup and restore the system clipboard in C#?

0

精彩评论

暂无评论...
验证码 换一张
取 消