Moin Leute.
Problem war die Auswertung des MouseWheel-Events auf einer PictureBox, um in einem Stapel von Bildern zu wechseln, nicht aber die Bildposition oder den Zoomfaktor zu ändern.
Einen freundlichen Dank an
PictureBox, Label und Co. reagieren nicht auf das MouseWheel-Event, sie sind passiv.
Wie sich herausstellte, gibt es unter Win7 und Win8.1 einerseits und Win10 andererseits große Unterschiede.
Außerdem gibt (unter W7 und W8.1) es bezüglich des MouseWheel-Events "gutartige" und "bösartige" Controls.
"Gutartige" Controls sind Controls, die auf das MouseWheel-Event reagieren, wenn die Maus über ihnen ist, z.B. die RichTextBox.
"Bösartige" Controls sind Controls, die das MouseWheel-Event claimen, wenn sie den Eingabefokus haben, z.B. das NumericUpDown oder die TrackBar.
Zu den Code-Beispielen.
In einer RichTextBox, einem Label und einem Nicht-Autoscroll-Panel werden Zahlen ausgegeben, die mit der Scroll-Richtung incrementiert oder decrementiert werden.
NumericUpDown und TrackBar verändern ihr Value.
Das MouseWheel-Event der RichTextBoxen ist eigentlich nicht erforderlich, der vorhandene Text, so er länger als die Anzeige ist, wird gescrollt.
Um denselben visuellen Eindruck wie bei den passiven Controls zu erzeugen, bekommt die RichTextBox ebenfalls einen zählenden Wert im eigenen Eventhandler.
Zum Prinzip:
Unter Win10 ist es ganz einfach.
Die Form aboniert das globale MouseWheel-Event und verteilt es, je nach von der Maus überstrichenem passiven Control, auf dieses.
Aktive Controls bekommen keinen separaten Eventhandler.
Ausnahme ist die RichTextBox, wie oben erläutert.
Unter Win7 und Win8.1 ist das etwas komplizierter.
Alle aktiven Controls bekommen denselben Eventhandler.
Die "bösartigen" Controls müssen abgeleitet werden, um freiwillig das MouseWheel-Event abzugeben, wenn das Control nicht mehr von der Maus überstrichen wird.
"Bösartige" Conrols werden aktiviert, wenn die Maus auf ihnen ist, ansonsten werden sie deaktiviert.
exemplarisch für ein "bösartiges" Control
Test, ob sich die Maus auf einem Control befindet
Der Rest ist dann wieder einfach, jedes Control reagiert auf sein eigenes Event im globalen Event-Handler.
Viel Spaß
PictureBoxMouseWheel.W7.zip
PictureBoxMouseWheel.W10.zip
Problem war die Auswertung des MouseWheel-Events auf einer PictureBox, um in einem Stapel von Bildern zu wechseln, nicht aber die Bildposition oder den Zoomfaktor zu ändern.
Einen freundlichen Dank an
Stackoverflow
, wo einige Grundlagen diskutiert wurden: stackoverflow.com/questions/33…eel-event-with-pictureboxPictureBox, Label und Co. reagieren nicht auf das MouseWheel-Event, sie sind passiv.
Wie sich herausstellte, gibt es unter Win7 und Win8.1 einerseits und Win10 andererseits große Unterschiede.
Außerdem gibt (unter W7 und W8.1) es bezüglich des MouseWheel-Events "gutartige" und "bösartige" Controls.
"Gutartige" Controls sind Controls, die auf das MouseWheel-Event reagieren, wenn die Maus über ihnen ist, z.B. die RichTextBox.
"Bösartige" Controls sind Controls, die das MouseWheel-Event claimen, wenn sie den Eingabefokus haben, z.B. das NumericUpDown oder die TrackBar.
Zu den Code-Beispielen.
In einer RichTextBox, einem Label und einem Nicht-Autoscroll-Panel werden Zahlen ausgegeben, die mit der Scroll-Richtung incrementiert oder decrementiert werden.
NumericUpDown und TrackBar verändern ihr Value.
Das MouseWheel-Event der RichTextBoxen ist eigentlich nicht erforderlich, der vorhandene Text, so er länger als die Anzeige ist, wird gescrollt.
Um denselben visuellen Eindruck wie bei den passiven Controls zu erzeugen, bekommt die RichTextBox ebenfalls einen zählenden Wert im eigenen Eventhandler.
Zum Prinzip:
Unter Win10 ist es ganz einfach.
Die Form aboniert das globale MouseWheel-Event und verteilt es, je nach von der Maus überstrichenem passiven Control, auf dieses.
Aktive Controls bekommen keinen separaten Eventhandler.
Ausnahme ist die RichTextBox, wie oben erläutert.
Unter Win7 und Win8.1 ist das etwas komplizierter.
Alle aktiven Controls bekommen denselben Eventhandler.
Die "bösartigen" Controls müssen abgeleitet werden, um freiwillig das MouseWheel-Event abzugeben, wenn das Control nicht mehr von der Maus überstrichen wird.
"Bösartige" Conrols werden aktiviert, wenn die Maus auf ihnen ist, ansonsten werden sie deaktiviert.
C#-Quellcode
- using System.Windows.Forms;
- namespace PictureBoxMouseWheel
- {
- /// <summary>
- /// Klasse zum freundlichen Behandeln des
- /// MouseWheel-Events unter Windows 7 und 8.1
- /// </summary>
- public class MyNumericUpDown
- : NumericUpDown
- {
- /// <summary>
- /// Flag zum Deaktivieren "bösartigen" Controls
- /// </summary>
- public bool IsActive = false;
- /// <summary>
- /// Event für das MainWindow zum re-aquirieren
- /// des MouseWheel-Events
- /// </summary>
- public event MouseEventHandler MyMouseWheel = delegate { };
- /// <summary>
- /// das eigentliche MouseWheel-Event
- /// </summary>
- protected override void OnMouseWheel(MouseEventArgs e)
- {
- // globales MouseWheel-Event
- this.MyMouseWheel(this, e);
- if (this.IsActive)
- {
- // nur aktive Controls dürfen ihr MouseWheel-Event abarbeiten
- base.OnMouseWheel(e);
- }
- }
- }
- }
C#-Quellcode
- /// <summary>
- /// Testen, ob die Maus auf dem gegebenen Control ist
- /// </summary>
- private bool CheckMousePos(Control ctrl)
- {
- // Do not use MouseEventArgs.X, Y because they are relative!
- Point mousePos = Control.MousePosition;
- do
- {
- Rectangle rect = ctrl.RectangleToScreen(ctrl.ClientRectangle);
- if (!rect.Contains(mousePos))
- {
- return false; // mouse position is outside the picturebox or it's parents
- }
- ctrl = ctrl.Parent;
- }
- while (ctrl != null && ctrl != this);
- // here you have the mouse position relative to the pictureBox if you need it
- return true;
- }
Viel Spaß
PictureBoxMouseWheel.W7.zip
PictureBoxMouseWheel.W10.zip
Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch
Ein guter .NET-Snippetkonverter (der ist verfügbar).
Programmierfragen über PN / Konversation werden ignoriert!
Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch
Ein guter .NET-Snippetkonverter (der ist verfügbar).
Programmierfragen über PN / Konversation werden ignoriert!