Подтвердить что ты не робот

Есть ли способ отключить функцию "двойной щелчок для копирования" на ярлыке .NET?

Это действительно раздражает. Я использую ярлык как часть элемента управления элемента списка, где пользователь может щелкнуть его, чтобы выбрать элемент списка, и дважды щелкнуть его, чтобы переименовать его. Однако, если у вас было имя в буфере обмена, двойной щелчок на ярлыке заменит его текстом метки.

Я также проверяю другие метки в приложении, и они также будут скопированы в буфер обмена с двойным щелчком. Я не написал код буфера обмена в этой программе, и я использую стандартные метки .NET.

Есть ли способ отключить эту функцию?

4b9b3361

Ответ 1

Я смог сделать это, используя комбинацию других ответов. Попробуйте создать этот производный класс и замените любые метки, которые вы хотите отключить с помощью функции буфера обмена:

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

Ответ 2

Я нашел этот пост. Последнему плакату, похоже, было дано решение от Microsoft, хотя и не идеальное решение.

Ответ 3

Решение TKTS, преобразованное в С#

Для начинающих: (добавьте новый класс, создайте, перейдите к дизайнеру и перетащите его в положение "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);
    }

}

Ответ 4

Когда внутреннее текстовое значение пустое, дважды нажмите на метку, не пытаясь скопировать текстовое значение в буфер обмена. Этот метод более чист, чем другие альтернативы, я думаю:

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

Ответ 5

Мое решение (ужасно уродливое, но, похоже, это работает) заключалось в том, чтобы скопировать текст буфера обмена в локальную переменную одним щелчком мыши и восстановить его при двойном щелчке, если буфер обмена отличается от локальной переменной. Очевидно, что предшественником двойного щелчка является первый щелчок, поэтому он работает.

Я собираюсь задать этот вопрос, потому что мне понравился бы более чистый метод!

Ответ 6

Я пробовал решения, опубликованные выше, и они не работали для меня. = (После этой основной идеи, хотя (спасибо выше), я приехал сюда, и это, похоже, работает (немного чище тоже). (Работает на 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, а затем восстанавливать их послесловие. В этом случае текст и картинки покрывают его для меня.

Одна полезная (и предостерегающая) ссылка на эту тему здесь: Как создать резервную копию и восстановить системный буфер обмена на С#?