2012-12-19 5 views
5

Wir haben ein sehr großes Kind-Steuerelement, das viel Rendering ausführt, um seine Details anzuzeigen, aber da nur ein Teil dieses Steuerelements tatsächlich sichtbar ist (es wird von etwas weiter oben in der Hierarchie beschnitten, nicht unbedingt sein unmittelbares Elternteil) wollen wir nur um den sichtbaren Teil während des OnRender-Aufrufs zu rendern.Gibt es eine einfache Möglichkeit, die sichtbaren Grenzen eines Steuerelements zu bestimmen, um das Rendering zu optimieren?

Betrachten Sie das folgende Bild. Das Kind ist 100x50, aber der sichtbare Bereich ist ein Rechteck mit Ecken bei (10,5) und (100,50) in Kindkoordinaten. Das ist der Bereich, den wir suchen.

Clipped Child

Hinweis: Sie können nicht einfach tun Koordinatenkonvertierungen vom Kind zum Vater und Test zum Aufstecken, weil es nicht die Eltern sein, die den Ausschnitt tun.

Betrachten Sie verschachtelte Canvas-Steuerelemente in einem ScrollViewer. Der innere Canvas kann sehr gut innerhalb der Grenzen des äußeren Canvas liegen, aber der äußere Canvas kann vom ScrollViewer abgeschnitten werden, so dass auch der innere Canvas von diesem visuell geclippt wird.

Wenn Sie den visuellen Baum durchlaufen und jedes Elternelement testen, wird die Leistung beeinträchtigt.

Gibt es in WPF so etwas, das die Grenzen des sichtbaren Bereichs eines Steuerelements erreichen kann?

+0

Dieser Thread könnte Ihnen helfen, was Sie wollen: http://stackoverflow.com/questions/1517743/in-wpf-how-can-i-determine-whether-a-control-is-visible -to-the-user –

+0

Nein! Das ist nur die Grenze, die überprüft wird (siehe oben meine Anmerkung). Das repräsentiert nicht wirklich, was sichtbar ist. – MarqueIV

+0

Nur ein Stich in die Dunkelheit - verwenden Sie Reflektor, um in die Interna der IsMouseDirectlyOver -Eigenschaft zu schauen (gefunden auf den meisten WPF-Steuerelementen, wahrscheinlich von FrameworkElement geerbt). Diese Eigenschaft durchschaut verschachtelte Objekte, um festzustellen, ob sich die Maus direkt über dem genauen spezifischen Steuerelement befindet. Ich denke, dass Sie in der Lage sein könnten, ähnliche Logik für die Überprüfung der Grenzen zu verwenden ... – Marko

Antwort

0

Ich würde vorschlagen, dass Sie innerhalb Ihrer OnRender-Methode Ihre sichtbaren Objekte mit besonderer Aufmerksamkeit auf ihre Z-Reihenfolge zusammenstellen oder rendern sollten, aber nicht unbedingt Zeit damit verbringen, sich Gedanken darüber zu machen, was sichtbar ist. Das ist nicht C++. Ein Teil des Grundgedankens hinter dem Design von WPF ist, dass das System in der Lage sein sollte, für Sie zu entscheiden, was sichtbar ist und was nicht. Es soll ein etwas höheres Abstraktionsniveau sein. Wenn Sie feststellen, dass Sie Code schreiben, um zu testen, was sichtbar ist und was die Grenzen dieses sichtbaren Teils sind, verwenden Sie ihn wahrscheinlich nicht richtig. Sei .. ein bisschen fauler. Das (was Sie oben beschrieben haben) soll ziemlich einfach sein.

Wenn Ihre sichtbaren Objekte herumgleiten oder sich in vertikaler Reihenfolge (dh Z-Reihenfolge) bewegen, werden sie einfach sichtbar oder nicht sichtbar. Wenn Sie möchten, dass etwas trotz seiner Position in der Z-Reihenfolge nicht sichtbar ist, machen Sie es unsichtbar (idealerweise indem Sie es an eine Eigenschaft binden, die Visibility.Visible, Visibility.Hidden oder Visibility.Collapsed ergibt).

Hinweis: Wenn ich verschiedene Implementierungen von Grafiken betrachte - insbesondere für Entwickler, die von anderen Plattformen aus auf WPF zugreifen, stelle ich oft fest, dass OnRender eigentlich nicht überschrieben werden muss. Wenn Sie nicht viele Grafiken haben, die in Echtzeit gerendert werden müssen, können Sie WPF oft die Arbeit für Sie erledigen lassen und einfach definieren, was Sie in Ihrem XAML anzeigen möchten.

+0

Das sind alles gute Punkte, aber sie gelten nicht. Wir * * tun eine Menge von benutzerdefinierten Rendering, die einfache (oder sogar komplexe) Bindungen nicht kümmern können, da sie aus Hunderten von Berechnungen bestehen können, bevor das Rendering tatsächlich passiert.Aber ihr Clip-Bereich kann sich aufgrund anderer Faktoren ändern, weshalb wir viel Zeit damit verbringen, Dinge zu rendern, die wir nie gesehen haben. Sie schlagen im Wesentlichen eine alternative Lösung für eine andere Frage vor, nicht für meine. Meine Frage war, einen Weg zu finden, den ausgeschnittenen Bereich zu bestimmen. Danke für Ihre Eingabe. Ich bin sicher, dass es anderen helfen kann. Nur nicht wir. – MarqueIV

+0

Und für die Aufzeichnung, ja, ich weiß in WPF, es sei denn, Sie haben mit sagen, das 'Rendering' im OnRender-Aufruf ist überhaupt nicht wirklich Rendering, sondern Caching Zeichnungsbefehle, die später während der ausgeführt werden tatsächliche Aufrufe, die an die Hardware rendern. Nehmen wir an, dass wir für diese Frage eine WriteableBitmap verwenden, die wir sehr oft in ihrer Gesamtheit neu erzeugen müssen. Wenn also etwas nicht wirklich sichtbar ist, wollen wir diesen Teil optimieren. – MarqueIV

+0

Ok, ich verstehe. Die meisten Q dieses Typs stammen von Entwicklern, die für WPF relativ neu sind, oder für einfachere Szenarien - eindeutig nicht der Fall. Ich kenne keine verallgemeinerte Verknüpfung. Ich habe 2 gemacht, die eine enorme Menge an komplexem Rendering erforderten: In einem Fall sollte der Inhalt horizontal verschoben werden (ein Scroll-Satz von Graphen). Also habe ich WritableBitmaps in Form von horizontal gestapelten Streifen konzeptionell organisiert. Da jeder Streifen nach links wegrutschte, wurde er außerhalb des Bildschirms markiert und umgekehrt, wenn Streifen rechts sichtbar wurden. Es hängt ganz von der geometrischen Natur der App ab – JamesWHurst

Verwandte Themen