2010-03-25 15 views
25

To naprawdę denerwujące. Używam etykiety jako elementu kontrolki użytkownika elementu listy, gdzie użytkownik może go kliknąć, aby wybrać element listy i kliknąć go dwukrotnie, aby zmienić nazwę. Jeśli jednak masz nazwę w schowku, dwukrotne kliknięcie etykiety zastąpi ją tekstem etykiety!Czy istnieje sposób wyłączenia funkcji "podwójnego kliknięcia, aby skopiować" etykiety .NET?

Sprawdziłem także inne etykiety w aplikacji, a one również będą kopiować do schowka za pomocą przycisku doubleclick. Nie napisałem żadnego kodu schowka w tym programie i używam standardowych etykiet .NET.

Czy istnieje sposób wyłączenia tej funkcji?

+2

Zgadnij - czy próbowałeś obsługiwać zdarzenie MouseDoubleClick i nic nie robić? –

+0

Mogę odtworzyć to na mojej maszynie Vista, ale nie na dwóch moich maszynach XP. – eschneider

+2

Austin - to nie działa, niestety. Tekst zostanie skopiowany do schowka przed uruchomieniem zdarzenia. –

Odpowiedz

3

Znalazłem this post. Wydaje się, że ostatni plakat dostał rozwiązanie od Microsoftu, choć nie jest to idealne rozwiązanie.

+2

Rozwiązanie przedstawione w tym poście wydaje się usuwać schowek, który jest bardziej odsunięty. Ale moim zdaniem trochę lepiej niż wcześniejsze zachowanie. –

+0

+1 za wpis, który pomógł mi z moim rozwiązaniem – TKTS

+0

Następnym razem skopiuj wpis i podaj link, abyśmy mieli kopię tutaj, wpis nie jest już ważny :( –

1

Moje rozwiązanie (strasznie brzydkie, ale wygląda na to, że działa) polegało na skopiowaniu tekstu schowka do zmiennej lokalnej za pomocą jednego kliknięcia i przywróceniu go po dwukrotnym kliknięciu, jeśli schowek różni się od zmiennej lokalnej. Oczywiście prekursorem dwukrotnego kliknięcia jest pierwsze jedno kliknięcie, dlatego to działa.

Zamierzam zagrać w to pytanie, ponieważ chciałbym mieć czystszą metodę!

+0

To jest "obejście" dosłownie ... dobrze. Musisz również sprawdzić typ danych, ponieważ nie zawsze jest to "Ciąg", który znajduje się w schowku ... także, jeśli schowek miał nawet pewne dane w pierwszej kolejności – Sree

7

Udało mi się to zrobić za pomocą kombinacji innych udzielonych odpowiedzi. Spróbuj tworzenia tej klasy pochodnej i zastąpić wszelkie etykiety chcesz wyłączyć funkcję schowka z nim:

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 
+0

To działało dla mnie, dziękuję Czuję, że ta odpowiedź powinna być teraz oznaczona jako poprawna, ponieważ zachowuje zawartość, która była już w schowku – Cuthbert

+1

Oczywiście, to tylko zachowuje tekst.Jeśli schowek zawiera wszystko w tych formatach trudne do obsługi w zarządzanym Kod, masz pecha, myślę, że najlepszym sposobem na zapisanie i przywrócenie całej zawartości byłaby para funkcji niezarządzanych – Medinoc

+0

Znacznie lepiej niż po prostu przejdź do 'Clipboard.GetDataObject(). GetFormats()' i zrób 'Dictionary ' zawierający _wszystko_ i przywróćmy to później. Chociaż używam rozwiązania Jaexa; to znacznie prostsze. – Nyerguds

2

rozwiązanie TKTS konwertowane do C#

dla początkujących: (dodać nową klasę, budować, iść do projektanta i z Toolbox przeciągnij i upuść pozycji o nazwie „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); 
    } 

} 
2

Kiedy wewnętrzna wartość tekstowa jest pusta następnie dwukrotne kliknięcie na etykiecie nie próbuje skopiować wartość tekstu do schowka. Ta metoda jest bardziej czysta niż inne alternatywy, które moim zdaniem:

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

Rzeczywiście, przetestowałem to i wydaje się, że używa on tylko prywatnej zmiennej tekstowej etykiety dla schowka, a nie własności publicznej. Bardzo osobliwe, ale wygląda na to, że funkcja Paint używa właściwości publicznej, więc to zastąpienie działa dobrze, co czyni to bardzo szybkim i czystym rozwiązaniem. – Nyerguds

0

Próbowałem rozwiązania przedstawione powyżej, a one nie działają dla mnie. = (Obserwuję, że podstawowa idea, choć (dzięki wyżej), przyjechałem tutaj, a to wydaje się działać (trochę czystsze też). (W systemie 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); 
     } 
    } 
} 

Niektóre dodatkowy wysiłek miałby być zainwestowanym, aby zachować rzeczy takie jak skopiowane pola Excel i tym podobne, chociaż zasada byłaby taka sama.Jak wspomniano, można wykonać iterację w schowku dla wszystkich dostępnych formatów (lub tych, na których Ci zależy) i wprowadzić te wartości do Obiekt słownika, a następnie przywrócić je, w tym przypadku tekst i fotki pokrywają go w tym przypadku:

Jeden wart uwagi (i przestrogi) link do zobaczenia na ten temat jest tutaj: How do I backup and restore the system clipboard in C#?

Powiązane problemy