【问题标题】:Mousewheel bubbling up in winforms?鼠标滚轮在winforms中冒泡?
【发布时间】:2011-08-08 14:35:42
【问题描述】:

我对 winforms 和鼠标滚轮事件有一点问题。 我有一个代表滑块的自定义用户控件。现在,我有几组滑块,其中每组都包裹在一个面板内。然后,所有组都包装在另一个面板中(将 AutoScroll 设置为 true),并包装在一个表单中。滑块逻辑的实现使得鼠标滚轮可用于更改其值。为此,当鼠标悬停在滑块上时,滑块用户控件将获得焦点。但是,当我滚动时,AutoScroll 父面板也会随之滚动。 我已经在这个问题上浪费了很多时间。任何人都知道这里发生了什么以及我该如何解决它?我认为该事件正在冒泡到父面板,但是在 Slider 控件中处理它时,我没有在该事件上找到 Handled 属性(与 WPF 一样)。

非常感谢

【问题讨论】:

  • 我认为滚动只受焦点所在的项目的影响,而不仅仅是悬停在它上面。
  • @MPelletier 它不同。例如在 Outlook 中它是通过悬停,但在 Visual Studio 中它是通过焦点
  • 我使用 MouseEnter 事件来集中我的用户控件。这样我就可以在我的聚焦滑块 UserControl 上使用 MouseWheel。滚轮工作完美,唯一的问题是父面板也同时滚动。
  • 什么是“滑块”?在可滚动面板内使用 TrackBar 时,我没有得到任何重现。
  • @Hans Passant:我们将 Slider 实现为具有自己外观的完整自定义用户控件(继承 UserControl 类)。当鼠标悬停在控件上时,我们对用户控件进行选择(焦点),然后使用 MouseWheel 更改滑块的值。除了父 AutoScroll 面板也滚动的问题外,这非常有效。当鼠标离开用户控件时,焦点变为父控件,使用鼠标滚轮时滑块的滚动按预期停止。

标签: c# winforms scroll


【解决方案1】:

我们将 Slider 实现为具有自己外观的完整自定义用户控件(继承 UserControl 类)。

您可能已经注意到 UserControl 没有在“属性”窗口中显示 MouseWheel 事件。那里有麻烦的暗示。 WM_MOUSEWHEEL 消息冒泡。如果具有焦点的控件不处理它,则 Windows 将其传递给它的父级。如此反复,直到找到想要处理它的父窗口。您的案件中的专家组。

您需要在滑块控件中调用一些黑魔法。传递给 MouseWheel 事件的实际事件 args 对象不是事件签名所暗示的 MouseEventArgs 类型,而是 HandledMouseEventArgs。这可以让你停止冒泡。像这样:

    protected override void OnMouseWheel(MouseEventArgs e) {
        base.OnMouseWheel(e);
        // do the slider scrolling
        //..
        ((HandledMouseEventArgs)e).Handled = true;
    }

【讨论】:

  • 伙计,你是救生员。非常感谢你做的这些。我觉得这很令人不安,我在 MS 文档的任何地方都找不到这个解释。也许我看过了?
  • 你没有。使用 UserControl 而不是 Control,您遇到了麻烦。
【解决方案2】:

如果您正在动态创建事件,例如

object.event += new EventHandler<EventArgs>(eventfunction);

在这样调用事件函数后尝试取消注册事件

object.event -= new EventHandler<EventArgs>(eventfunction);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-15
    • 1970-01-01
    • 1970-01-01
    • 2012-09-30
    • 2014-10-01
    • 1970-01-01
    相关资源
    最近更新 更多