C# winforms-MouseWheel 事件由于控件属性而未触发

C# winforms- MouseWheel event not firing because of control properties

我对鼠标滚轮事件有很大的疑问。我试图找到任何类型的参考资料,但总能找到关于此事的不同主题的答案。我为整个表单制作了一个鼠标滚轮事件(也是全屏的,但无论鼠标在哪里它都应该工作)-MouseWheel+=ChangeLength;(或MouseWheel += new MouseEventHandler(ChangeLength);,没关系)和在它的第一行打断点,看看它是否有效。

没有。

我打开了一个空白项目来测试它,令人惊讶的是,它做到了!然后我寻找问题的根源,发现设计器中只有两行可以区分成功触发事件和根本不触发。这两行是-

 this.rater.TabIndex = 15;
 this.rater.Visible = false;

如果这些行中的任何一行未被注释,则滚动鼠标滚轮时没有任何反应,但如果这两行都被删除或注释,则工作正常。使用 Focus()、单击屏幕、在设计器之外更改属性和其他已知方法均无济于事。

我需要补充一点,rater 而不是 只是一个常规控件,这可能是这个奇怪问题的根源。它是一个名为 ShapeRater 的自定义控件。我真的不明白 VisibleTabIndex 属性为什么以及如何导致它,它们完全不相关!另外,我删除了其中一个评分者(导致问题的原因),因为另一个很好,但是一旦删除,之前正常的那个开始导致这个问题。

有人知道为什么会发生这种情况以及如何解决吗?


在此先致谢,如果我写得不够准确,请深表歉意。这是我在这个网站上的第一个问题。

可能当您使其不可见时,您正在将焦点推向其他控件(因为您的控件失去焦点并且当控件消失时焦点转移到其他地方)。获得焦点的特定控件也将取决于选项卡索引值,因为它类似于它落到的下一个或上一个控件。

请注意,对于自定义控件,单击鼠标不会自动获得焦点。例如,您需要在 MouseDown 活动中调用 Focus()

除此之外,为了使控件仅通过将鼠标移到它上面来获得鼠标滚轮事件,您必须将焦点放在 MouseEnter 中。类似于 MouseEnter += (s, e) => Focus();。不过,我不确定这是一个完美的解决方案,因为我认为您只需将鼠标移到其他控件上即可 'stealing' 获得焦点。

另一件我认为更好的事情是处理表单上每个控件的 MouseWheel 事件,然后在响应之前检查鼠标是否确实在您的区域内它。

例如:

HandleCreated += (s, e) => {
   var maybeForm = FindForm();
   if (maybeForm == null)
      return; // or throw since you should have a form by now
   var form = maybeForm;

   MouseEventHandler mouseScrollDelegate = (s, e) => MouseScroll(e.Delta);
   foreach (var control in form.Controls.Cast<Control>())
      control.MouseWheel += mouseScrollDelegate;
};

...

void MouseScroll(int pDelta) {
   var screenMouse = Cursor.Position;
   var clientMouse = PointToClient(screenMouse);
   if (!ClientRectangle.Contains(clientMouse))
      return;

   // do something
}

我知道很晚了,但我再次登录后发现我忘了关闭我的问题。 如果我没记错的话,这个问题与在应用程序中使用箭头后失去焦点有关,所以我最终为此更换了按键。