Есть ли способ отключить функцию "двойной щелчок для копирования" на ярлыке .NET?
Это действительно раздражает. Я использую ярлык как часть элемента управления элемента списка, где пользователь может щелкнуть его, чтобы выбрать элемент списка, и дважды щелкнуть его, чтобы переименовать его. Однако, если у вас было имя в буфере обмена, двойной щелчок на ярлыке заменит его текстом метки.
Я также проверяю другие метки в приложении, и они также будут скопированы в буфер обмена с двойным щелчком. Я не написал код буфера обмена в этой программе, и я использую стандартные метки .NET.
Есть ли способ отключить эту функцию?
Ответы
Ответ 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, а затем восстанавливать их послесловие. В этом случае текст и картинки покрывают его для меня.
Одна полезная (и предостерегающая) ссылка на эту тему здесь:
Как создать резервную копию и восстановить системный буфер обмена на С#?