c# - wpf-überschneidungen nicht Empfang von Maus-events

Baue ich ein canvas-Steuerelement. Diese root-Leinwand hat mehrere überlappende Kinder (Leinwand, wie gut). Ist dies getan, so dass jedes Kind handhaben kann, seine eigene Zeichnung, und ich kann ein und verfassen Sie dann das endgültige Ergebnis mit einer beliebigen Kombination von Kinder zu erhalten, das gewünschte Verhalten.

Ist dies funktioniert sehr gut, wie weit das Rendern betrifft. Diese funktioniert nicht so gut mit Maus-events allerdings. Die Weise Maus-events-arbeiten sind wie folgt (mit previewmousemove als Beispiel):

1 - Wenn root-Leinwand ist unter Maus, Feuer-event
2 - Kontrollieren Sie alle Kinder, wenn man unter die Maus, Feuer-event und stoppen

Als solche, nur das erste Kind, das ich hinzufügen, erhalten die mouse-move-Ereignis. Die Veranstaltung wird nicht weitergegeben, bis alle Kinder, weil Sie sich überlappen.

Um dies zu überwinden, ich habe versucht, die folgenden:
1 - Override-Maus-events im root-Leinwand
2 - Für jedes event, finden alle Kinder, die möchten, behandeln Sie das Ereignis mithilfe der VisualTreeHelper.HitTest
3 - Für alle Kinder, dass wieder ein Gültiger Treffer-test-Ergebnis (sprich: unter Maus und bereit zum verarbeiten des Ereignisses (IsHitTestVisible == true)), ???

Dies ist, wo ich geblieben bin, habe ich irgendwie das senden müssen Sie die Maus-Ereignis für alle Kinder, und beenden Sie den normalen Ablauf der Veranstaltung, um sicherzustellen, dass das erste Kind nicht bekommen es zweimal (über handled = true in das event).

Mittels RaiseEvent mit der gleichen Veranstaltung weitergegeben an die Kinder, die Dinge scheinen zu funktionieren, aber irgendwie löst das Ereignis auf dem übergeordneten (Stamm-Leinwand) sowie. Zur Umgehung dieses habe ich benötigt, um erstellen Sie eine Kopie des Ereignisses und der eingestellten Kraft gesetzt, die Quelle aber es scheint eher ein hack als eine Lösung. Gibt es eine richtige Weise, das zu tun, was ich versuche zu tun? Code-Beispiel folgt.

    public class CustomCanvas : Canvas
    {
        private List<object> m_HitTestResults = new List<object>();

        public new event MouseEventHandler MouseMove;

        public CustomCanvas()
        {
            base.PreviewMouseMove += new MouseEventHandler(CustomCanvas_MouseMove);
        }

        private void CustomCanvas_MouseMove(object sender, MouseEventArgs e)
        {
//Hack here, why is the event raised on the parent as well???
            if (e.OriginalSource == this)
            {
                return;
            }

                Point pt = e.GetPosition((UIElement)sender);
                m_HitTestResults.Clear();

                VisualTreeHelper.HitTest(this,
                    new HitTestFilterCallback(OnHitTest),
                    new HitTestResultCallback(OnHitTest),
                    new PointHitTestParameters(pt));

                MouseEventArgs tmpe = new MouseEventArgs(e.MouseDevice, e.Timestamp, e.StylusDevice);
                tmpe.RoutedEvent = e.RoutedEvent;
                tmpe.Source = this;

                foreach (object hit in m_HitTestResults)
                {
                    UIElement element = hit as UIElement;
                    if (element != null)
                    {
 //This somehow raises the event on us as well as the element here, why???
                        element.RaiseEvent(tmpe);
                    }
                }


            var handlers = MouseMove;
            if (handlers != null)
            {
                handlers(sender, e);
            }

            e.Handled = true;
        }

        private HitTestFilterBehavior OnHitTest(DependencyObject o)
        {
            UIElement element = o as UIElement;
            if (element == this)
            {
                return HitTestFilterBehavior.ContinueSkipSelf;
            }
            else if (element != null && element.IsHitTestVisible && element != this)
            {
                return HitTestFilterBehavior.Continue;
            }
            return HitTestFilterBehavior.ContinueSkipSelfAndChildren;
        }

        private HitTestResultBehavior OnHitTest(HitTestResult result)
        {
            //Add the hit test result to the list that will be processed after the enumeration.
            m_HitTestResults.Add(result.VisualHit);
            //Set the behavior to return visuals at all z-order levels.
            return HitTestResultBehavior.Continue;
        }
  • Beachten Sie, dass werde ich auch brauchen, das arbeiten mit tooltips im inneren Kinder der Kinder von der Wurzel Leinwand.
  • Ist das für silverlight? WPF? Fügen Sie die entsprechenden tags, erhalten Sie eine Antwort schneller.
InformationsquelleAutor | 2009-04-11
Schreibe einen Kommentar