myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » GUI: WPF und XAML » MouseLeave Event wird nicht zuverlässig ausgelöst
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

MouseLeave Event wird nicht zuverlässig ausgelöst

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
Ramokthan Ramokthan ist männlich
myCSharp.de-Mitglied

Dabei seit: 29.11.2012
Beiträge: 23
Entwicklungsumgebung: Microsoft Visual Studio 2017
Herkunft: Karlsruhe


Ramokthan ist offline

MouseLeave Event wird nicht zuverlässig ausgelöst

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,

da ich neu hier bin versuch ich mein erstes Thema so gut wie möglich zu gestalten ^^

Mein Problem: Ich habe im Rahmen einer mittelgroßen Silverlightanwendung an mehreren Stellen Menü-Popups (vom Typ StackPanel) die teils durch MoueOver Events oder über MouseRightClick ausgelöst werden. Das funktioniert auch zuverlässig, nun habe ich jedoch das Problem, dass diese Menüs nicht immer Ordnungsgemäss geschlossen werden wenn ich mit der Maus den Stackpanel verlasse. "Nicht immer" heißt in diesem Fall: wenn ich mit der Maus sehr schnell den Bereich des Stackpanels verlasse, verlasse ich ihn (vergleichsweise) langsam, wird das Menü bzw. der Stackpanel ordnungsgemäß geschlossen (ausgeblendet).
Ich habe mir diesbezüglich schon Gedanken über Workarounds gemacht wie zb die Archivierung aller geöffneten Mouseover Menüs und nach jeder Mausbewegung zu prüfen ob die Maus noch auf einem von diesen Ruht, aber eine ideale Lösung scheint mir dies nicht (zumal das sich nicht sehr performant anhört).

Ich versuche mal mit ein Paar codebeispielen ein Bild zu geben wie das ganze aufgebaut ist, grundsätzlich funktioniert es ja, nur scheinbar kommt das Mouseleave Event nicht mit der Geschwindigkeit der Maus mit. ^^

Der Konstruktor der Menü Klasse:

C#-Code:
public CContextMenu(object objMain, Canvas objCanvas)
        {
            if (objMain != null)
            {
                if (this.objMain.getCurrentUIElement() != null && this.objMain.objContextMenu == null)
                             this.objMain.getCurrentUIElement().MouseEnter += new MouseEventHandler(CContextMenu_MouseOver);
            }

            this.objCanvas = objCanvas;
        }

Die (eine von vielen :-D ) Initialisierung:

C#-Code:
if (this.objContextMenu == null) this.objContextMenu = new CContextMenu(this, this.objCanvas, this.objTextBlock);
            else this.objContextMenu.clearMenues();

Die Funktionen (sehr aufs wesentliche gekürzt, ich hoffe nicht zuviel):

C#-Code:
public void CContextMenu_MouseOver(object sender, MouseEventArgs e)
        {
            CContextMenu_MouseRightButtonDown(sender,null);
        }

        // Mouse right click event for visual object
        public void CContextMenu_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {

if (this.objContextMenu == null)
                {
                    this.objContextMenu = new Border();
                    ((Border)this.objContextMenu).BorderBrush = new SolidColorBrush(Color.FromArgb(255, 153, 153, 153));
                    ((Border)this.objContextMenu).BorderThickness = new Thickness(1);
                    LinearGradientBrush objBrush = new LinearGradientBrush();
                    objBrush.EndPoint = new Point(0.5, 1);
                    objBrush.StartPoint = new Point(0.5, 0);
                    GradientStop objGradientStop = new GradientStop();
                    objGradientStop.Color = Colors.White;
                    objBrush.GradientStops.Add(objGradientStop);
                    objGradientStop = new GradientStop();
                    objGradientStop.Color = Color.FromArgb(255, 150, 183, 249);
                    objGradientStop.Offset = 1;
                    objBrush.GradientStops.Add(objGradientStop);
                    (this.objContextMenu as Border).Background = objBrush;
                    DropShadowEffect objEffect = new DropShadowEffect();
                    this.objContextMenu.Effect = objEffect;

                    StackPanel objStackPanel = new StackPanel();
                    objStackPanel.HorizontalAlignment = HorizontalAlignment.Left;
                    objStackPanel.VerticalAlignment = VerticalAlignment.Top;

                    objStackPanel.MouseLeave += new MouseEventHandler(this.ContextMenu_MouseLeave);

((Border)this.objContextMenu).Child = objStackPanel;
                    this.objContextMenu.SetValue(Canvas.ZIndexProperty, 100);
                    this.objContextMenu.UpdateLayout();
                    this.objContextMenu.Visibility = Visibility.Collapsed;

CSingelton.objMainPage.OutCanvas.Children.Add(this.objContextMenu);
}
}

// Event for mouse leave from context menu
        protected virtual void ContextMenu_MouseLeave(object sender, object e)
        {
            if (this.objContextMenu != null) this.objContextMenu.Visibility = Visibility.Collapsed;
        }

Das sollte und bewirkt auch was es sollte: ein Öffnen des Stackpanels nach dem Kontakt mit dem Mauszeiger und ein Schließen beim (langsamen) verlassen. Nur möchte ich einfach diesen Wust nicht haben von offenen nicht benutzten Menüs (Auch wenn man daraus ein Spiel machen könnte: wieviele Menüs schaffst du gleichzeitig offen zu haben :-D ) wenn man mit der Maus schnell über ein Objekt fährt, da das Menü sich dann zwar öffnet, aber nicht mehr korrekt schließt, sollte man mit der Maus zu schnell sein. Die Menüs lassen sich zwar im nachhinein schließen wenn man mit der Maus wieder auf das Menü geht und dann dieses wieder (langsam) verlässt, aber auch diesen Workaround, das finde ich, sollte man doch irgendwie vermeiden können.

Habt ihr da eine Idee an was es da hängen könnte oder ist das ein allgemeines Problem?

Grüße,
Ramokthan

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Ramokthan am 30.11.2012 14:59.

30.11.2012 14:59 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
dN!3L dN!3L ist männlich
myCSharp.de-Poweruser/ Experte

avatar-2985.png


Dabei seit: 13.08.2004
Beiträge: 2.891


dN!3L ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Das ist ein allgemeines Problem. Tritt z.B. auch bei Winforms-Anwendungen auf.

Lösen kann man das z.B. durch einen Timer, der beim Einblenden des Menüs ausgelöst wird und dann (nach einer gewissen Zeit) prüft, ob sich der Mauszeiger noch über dem Menü-Control (bzw. plus einen gewissen Toleranzbereich drumherum) befindet.
Das hat auch den Vorteil, dass man nicht die ganze Zeit den Cursor exakt über dem Menü-Control befinden muss. Denn eigentlich verschwinden Menüs auch gar nicht sofort, wenn man sie verlässt.
30.11.2012 16:39 Beiträge des Benutzers | zu Buddylist hinzufügen
Ramokthan Ramokthan ist männlich
myCSharp.de-Mitglied

Dabei seit: 29.11.2012
Beiträge: 23
Entwicklungsumgebung: Microsoft Visual Studio 2017
Herkunft: Karlsruhe

Themenstarter Thema begonnen von Ramokthan

Ramokthan ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Okay, allgemeines problem und nicht meine doofheit ^^

Ich werde das mal so ins Auge fassen mit dem Timer, schaffen werd ich das selber, danke für den Tipp. Daumen hoch
30.11.2012 17:35 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 7 Jahre.
Der letzte Beitrag ist älter als 7 Jahre.
Antwort erstellen


© Copyright 2003-2020 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 11.07.2020 13:16