FrameworkElement.EffectiveViewportChanged Ereignis

Definition

Tritt auf, wenn sich der effektive Viewport des FrameworkElements ändert.

// Register
event_token EffectiveViewportChanged(TypedEventHandler<FrameworkElement, EffectiveViewportChangedEventArgs const&> const& handler) const;

// Revoke with event_token
void EffectiveViewportChanged(event_token const* cookie) const;

// Revoke with event_revoker
FrameworkElement::EffectiveViewportChanged_revoker EffectiveViewportChanged(auto_revoke_t, TypedEventHandler<FrameworkElement, EffectiveViewportChangedEventArgs const&> const& handler) const;
public event TypedEventHandler<FrameworkElement,EffectiveViewportChangedEventArgs> EffectiveViewportChanged;
function onEffectiveViewportChanged(eventArgs) { /* Your code */ }
frameworkElement.addEventListener("effectiveviewportchanged", onEffectiveViewportChanged);
frameworkElement.removeEventListener("effectiveviewportchanged", onEffectiveViewportChanged);
- or -
frameworkElement.oneffectiveviewportchanged = onEffectiveViewportChanged;
Public Custom Event EffectiveViewportChanged As TypedEventHandler(Of FrameworkElement, EffectiveViewportChangedEventArgs) 

Ereignistyp

Windows-Anforderungen

Gerätefamilie
Windows 10, version 1809 (eingeführt in 10.0.17763.0)
API contract
Windows.Foundation.UniversalApiContract (eingeführt in v7.0)

Hinweise

Ein Bildlaufsteuerelement ermöglicht es dem Benutzer, Inhalte zu schwenken/zu scrollen, die mehr Speicherplatz in Anspruch nehmen als auf der Benutzeroberfläche verfügbar sind. Der Teil des Inhalts, den der Benutzer sieht, wird als Viewport bezeichnet.

Das EffectiveViewportChanged-Ereignis stellt mehrere Informationen bereit:

  1. Der tatsächliche EffectiveViewport
  2. Eine Berechnung für den MaxViewport
  3. Skalare Werte für BringIntoViewDistanceX und BringIntoViewDistanceY

EffectiveViewport

Der EffectiveViewport ist die Schnittmenge aller bekannten Viewports, die das FrameworkElement in ihrer Unterstruktur enthalten. Wenn zwei oder mehr Viewports vorhanden sind (z. B. ein ScrollViewer , der in einem anderen ScrollViewer geschachtelt ist), die sich nicht überlappen, ist der EffectiveViewport ein leeres Rect.

Hinweis

Damit der Viewport eines Scrollsteuerelements dem Framework bekannt ist, muss das Steuerelement es zuvor mit der UIElement.RegisterAsScrollPort-Methode registriert haben. Das Framework verwendet den Clip des registrierten Elements, um den effektiven Viewport zu bestimmen.

Wenn sich der Viewport des Bildlaufsteuerelements ändert, muss es seine InvalidateViewport-Methode aufrufen, um das Framework darüber zu informieren, dass sich sein Viewport geändert hat und dass jedes seiner Unterelemente, die auf den effektiven Viewport lauschen, über Änderungen benachrichtigt werden muss.

Der EffectiveViewport wird im Koordinatenraum des FrameworkElements angegeben. Es ist nicht erforderlich, ein TransformToVisual mit dem Viewport Rect durchzuführen.

In einem einfachen Szenario, in dem es einen ScrollViewer gibt, der ein einzelnes Element enthält, stellt das EffectiveViewportChanged-Ereignis Viewport-Updates bereit, die dem ViewChanged-Ereignis ähneln. Der Standard Unterschied besteht darin, dass das EffectiveViewportChanged-Ereignis nach dem Layoutdurchlauf ausgelöst wird.

Diese ...

<ScrollViewer>
    <Grid Height="4000" Width="4000"
          EffectiveViewportChanged="Grid_EffectiveViewportChanged"/>
</ScrollViewer>

... bietet ähnliche Viewportinformationen wie diese...

<ScrollViewer ViewChanged="ScrollViewer_ViewChanged">
    <Grid Height="4000" Width="4000"/>
</ScrollViewer>

MaxViewport

Der MaxViewport ähnelt dem EffectiveViewport, stellt aber nicht eine einfache Schnittmenge der bekannten Viewports dar, sondern stellt die Schnittmenge der Viewports dar, als ob jeder einzelne äußere Viewport in Sicht genommen worden wäre. Das resultierende Rect stellt zwei Dinge dar:

  1. die größte Größe, die der EffectiveViewport haben kann (angesichts der aktuellen Viewportgrößen), und
  2. die Position des maximal effektiven Viewports relativ zum FrameworkElement.

Diese Informationen können verwendet werden, um zu ermitteln, wo und wie viel Inhalt das FrameworkElement vorab generieren sollte, um den Viewport zu füllen, bevor er in die Ansicht gescrollt wird.

Hinweis

Das Scrollen über eine direkte Eingabe wie Toucheingabe oder Stift wird vom System in einem separaten Prozess verarbeitet. Standardmäßig wird der Bildlauf asynchron zum UI-Thread verarbeitet. Steuerelemente, die die Virtualisierung durchführen, müssen aufgrund der inhärenten Kosten für die Elementerstellung möglicherweise Inhalte vorab generieren, bevor sie in den Viewport gelangen.

Das Verzögern aller Inhaltsvorbereitungen bis zum Anzeigen kann zu einer schlechten Bildlauferfahrung für Benutzer führen. Benutzer können Leerzeichen oder Stottern sehen, beide Symptome, dass der UI-Thread nicht mit der Geschwindigkeit des Verschiebens Schritt halten kann.

Die Position des MaxViewports wird im Koordinatenraum des FrameworkElement gemeldet. Wenn der MaxViewport in den Koordinatenraum des ersten Viewports in der Vorgängerkette von FrameworkElement transformiert würde, würde sich der Rect innerhalb der Grenzen dieses ersten Viewports befinden.

BringIntoViewDistanceX und Y

Diese Werte geben an, wie nahe das FrameworkElement ist, um in allen Viewports maximal sichtbar zu werden.

Wenn der Wert größer als 0, aber kleiner als der ActualWidth / ActualHeight ist, befindet sich das Element teilweise innerhalb des vom Benutzer sichtbaren Viewports. Wenn die Werte 0 sind, befindet sich das FrameworkElement vollständig innerhalb des vom Benutzer sichtbaren Viewports.

Tipp

Dies garantiert nicht, dass das Element für den Benutzer sichtbar ist, da andere Elemente mit einer höheren Z-Reihenfolge das FrameworkElement möglicherweise weiterhin verschließen.

Formaler ausgedrückt, sind diese Werte die Summe der absoluten Entfernung, die das FrameworkElement beim Erfüllen eines Aufrufs von StartBringIntoView übersetzt würde. Die Werte berücksichtigen nicht die Möglichkeit, dass ein Scrollsteuerelement den Bildlauf deaktiviert hat.

<ListView x:Name="lv">
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="x:String">
            <UserControl Tag="{x:Bind}"
                         EffectiveViewportChanged="Item_EffectiveViewportChanged"/>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>
private void Item_EffectiveViewportChanged(FrameworkElement sender, EffectiveViewportChangedEventArgs args)
{
    // If we wanted to know if a list item (w/ vertical scrolling only) is partially within the viewport
    // then we can just check the BringIntoViewDistanceY of the event args.  If the distance is 0 then the item is fully within
    // the effective viewport.  If the BringIntoViewDistanceY is less than the sender's ActualHeight, then its
    // partially within the effective viewport.
    // The EffectiveViewport rect is relative to the sender, so we can use it to know where the element is within the viewport.  
    // NOTE: "Within the viewport" != visible to the user's eye, since another element may overlap and obscure it.
    if (args.BringIntoViewDistanceY < sender.ActualHeight)
    {
        Debug.WriteLine($"Item: {sender.Tag} has {sender.ActualHeight - args.BringIntoViewDistanceY} pixels within the viewport");
    }
    else
    {
        Debug.WriteLine($"Item: {sender.Tag} has {args.BringIntoViewDistanceY - sender.ActualHeight} pixels to go before it is even partially visible");
    }

    // Consider disconnecting from the effective viewport when not needed.  Otherwise, it is called on every viewport change.
    //lv.EffectiveViewportChanged -= Item_EffectiveViewportChanged;
}

Verhalten

  • Wenn sich der effektive Viewport eines übergeordneten und untergeordneten Elements ändert, erhält das übergeordnete Element die Benachrichtigung vor dem untergeordneten Element.
  • Das Ereignis wird nur für Elemente in der Ui-Struktur ausgelöst, die am Layout teilnehmen. Wenn sich das Element beispielsweise nicht in der Livestruktur befindet oder die Visibility-Eigenschaft des Elements oder einer seiner Vorgänger auf Reduziert festgelegt ist, wird dieses Ereignis nicht ausgelöst.
  • Obwohl der effektive Viewport Rendertransformationen für alle Elemente berücksichtigt, berücksichtigt er nicht die Auswirkungen des Abschneidens (mit Ausnahme des Clips des Elements, das von einem Scrollsteuerelement als Viewport registriert wurde).
  • Der effektive Viewport berücksichtigt keine Okklusion, da andere Elemente eine höhere Z-Reihenfolge aufweisen.

Gilt für:

Weitere Informationen