一次点击调用 Click 和 LinkClicked 事件处理程序

one click calls both Click and LinkClicked event handlers

LinkLabel label = new LinkLabel();
// imagine there is a code to initialize the label
label.Click += (sender, args) => callback1();
label.LinkClicked += (sender, args) => callback2();

如果我在任何地方单击标签而不是它的 link,则会调用 callback1(),这是正确的。
如果我单击标签的 link,则会调用 callback1()callback2()

如何让它只调用 callback2()

我不知道有什么办法可以做到这一点。

如您在 reference source 中所见,LinkLabel 源自 LabelClick 事件由 Label 基础 class 引发。您可以在代码中看到 OnMouseDownOnMouseUp 等基本方法总是在 LinkLabel 处理这些事件之前被调用。

因此 Label 基本实现将始终在 LinkClicked 实现引发 LinkLabel 事件之前引发 Click 事件。没有 属性 或标志来阻止这种情况。

希望你能以不同的方式实现你想要的。

我能想到的两种解决方案。第一个非常愚蠢,但看起来非常有效。当鼠标悬停在 link 上时,您不喜欢单击。这有一个副作用,鼠标光标会改变。所以你可以通过检查光标形状来过滤:

private void linkLabel1_Click(object sender, EventArgs e) {
    if (Cursor.Current == Cursors.Default) {
       Debug.WriteLine("Click!");
       // etc...
    }
}

如果您有很多 link 标签,更有原则和方便的一点是当鼠标悬停在 link 上时根本不引发 Click 事件。向您的项目添加一个新的 class 并粘贴此代码:

using System;
using System.Windows.Forms;

class LinkLabelEx : LinkLabel {
    protected override void OnClick(EventArgs e) {
        var loc = this.PointToClient(Cursor.Position);
        if (this.PointInLink(loc.X, loc.Y) == null) base.OnClick(e);
    }
}