双击.NET Label控件将其文本复制到Vista +上的剪贴板?

时间:2013-06-11 15:47:07

标签: c# .net vb.net

当我在视觉工作室中搜索整个项目时,单词' clipboard'我找不到匹配。

但不知怎的,我的程序似乎正在将我的剪贴板的内容更改为等于我的表单上的控件的.text属性。怎么会这样?

我已经确定了处理程序,之后我的剪贴板似乎总是被更改,并添加了一个消息框以从剪贴板中获取文本以尝试识别何时可以更改它。

MessageBox.Show(Clipboard.GetText)

即使在处理事件的子顶部,我的剪贴板也已更改为控件的.text属性。这是处理此事件的唯一子,并且剪贴板在此事件后始终更改。

这是一个用vb.net编写的小型winforms项目。

更多信息:

当我点击它时,我的剪贴板被设置为标签的.text属性。标签在这里制作:

For i = 0 To lstTupChildren.Count - 1
    Dim lbl As New Label()
    lbl.Size = New System.Drawing.Size(250, 25)
    lbl.Font = New System.Drawing.Font("Calibri (body)", 10)
    lbl.Text = i + 1 & ". " & lstTupChildren(i).Item1
    lbl.Location = New System.Drawing.Point(0, 25 * i)
    If lstTupChildren(i).Item3 = True Then lbl.BackColor = Color.GreenYellow Else lbl.BackColor = Color.Orange 'sets the colour depending on whether the timesheet is active'
        Me.Controls.Add(lbl)
        AddHandler lbl.DoubleClick, AddressOf subChangeTimesheetState 'adds handler for double click to change status
        'adds handlers for moving the overlay
        AddHandler lbl.MouseDown, AddressOf Form_MouseDown
        AddHandler lbl.MouseMove, AddressOf Form_MouseMove
        'adds handler for hide context menu'
        AddHandler lbl.MouseClick, AddressOf subRightClickMenu

    Next

即使我注释掉处理程序:     AddHandler lbl.DoubleClick,AddressOf subChangeTimesheetState

我的剪贴板仍在更改。

可以在这里找到解决方法:在这里解决:http://www.aspnet-answers.com/microsoft/NET-WinForms-Controls/32231136/double-click-label-and-its-text-appears-on-the-clipboard.aspx

创建一个继承标签的新类,vb代码:

Public Class myLabel

Inherits Label
Private WM_GETTEXT As Integer = &HD
Private WM_LBUTTONDBLCLK As Integer = &H203
Private doubleclickflag As Boolean = False
Protected Overrides Sub WndProc(ByRef m As Message)
    If m.Msg = WM_LBUTTONDBLCLK Then
        doubleclickflag = True
    End If
    If m.Msg = WM_GETTEXT AndAlso doubleclickflag Then
        doubleclickflag = False
        Return
    End If
    MyBase.WndProc(m)
End Sub

结束班

4 个答案:

答案 0 :(得分:12)

这不是您的代码,而是Windows Vista中引入的“功能”。

在Windows Vista中,Windows Shell程序员检查了更改(更改列表中没有规范/对齐)更改了默认标签控件,以便在双击时将其文本复制到剪贴板。

此更改通常不会影响C ++应用程序,因为它们创建/托管标签控件,但它会影响所有VS.NET应用程序。当我在Win7时间框架中发现这个时,我向(惊讶的)框架团队提交了一个错误,但他们害怕修复这个错误,因为它存在了很长时间。

这是重复的Is there any way to disable the "double-click to copy" functionality of a .NET label?

答案 1 :(得分:4)

让标签在双击时不作出反应的最好方法是通过覆盖标签类本身来覆盖类样式。

    private class SingleClickLabel : Label
    {
        protected override CreateParams CreateParams
        {
            get
            {
                new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();

                CreateParams cp = base.CreateParams;
                cp.ClassStyle &= ~0x0008;
                cp.ClassName = null;

                return cp;
            }
        }
    }

这将从标签中删除CS_DBLCLKS窗口类样式。 从现在开始触发的唯一事件是每次发生的每次点击都会发生Click事件。

请参阅: http://msdn.microsoft.com/en-us/library/windows/desktop/ff729176(v=vs.85).aspx http://msdn.microsoft.com/en-us/library/system.windows.forms.createparams(v=vs.110).aspx

答案 2 :(得分:1)

我想有很多不同的方法可以解决同样的问题。这是我提出的(使用继承的标签,在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对象中,然后在之后恢复它们。在这种情况下,文字和图片适合我。

有关此主题的一个有价值的链接在这里: How do I backup and restore the system clipboard in C#?

答案 3 :(得分:0)

我已经为 Visual Basic NET 开发了这段代码。 这样当双击Label控件时,它的文本不会自动复制到Windows剪贴板,也可以使用它的双击事件。所需要的是使用与我们正在使用的标签具有相同属性的第二个标签。


Private TimeSpan1 As New TimeSpan
Private CursorPos1 As Point
Private Declare Function GetDoubleClickTime Lib "user32" Alias "GetDoubleClickTime" () As Integer

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    With Label2
        .Text = Label1.Text
        .BackColor = Label1.BackColor
        .Location = Label1.Location
        .Size = Label1.Size
        ' and other visual properties (if different)
    End With
End Sub

Private Sub Label1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) _
    Handles Label1.MouseDown, Label2.MouseDown

    sender.SendToBack()  

    If (CursorPos1.X = Cursor.Position.X) And (CursorPos1.Y = Cursor.Position.Y) Then
        TimeSpan1 = Now - CDate(Label1.Tag)
        If TimeSpan1.TotalMilliseconds < GetDoubleClickTime Then
           
        '  Label1_DoubleClick event code 

        End If
    End If

    CursorPos1 = Cursor.Position
    Label1.Tag = Now

End Sub