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

Hinweise

Ein Bildlaufsteuerelement ermöglicht dem Benutzer das Schwenken/Scrollen durch Inhalte, die mehr Platz in Anspruch nehmen, als auf der Benutzeroberfläche verfügbar ist. 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 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 Bildlaufsteuerelements dem Framework bekannt ist, muss das Steuerelement es zuvor mit der UIElement.RegisterAsScrollPort-Methode registriert haben. Das Framework verwendet den Clip des registrierten Elements bei der Bestimmung des effektiven Viewports.

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

Der EffectiveViewport wird im Koordinatenbereich des FrameworkElements angegeben. Es ist nicht erforderlich, transformToVisual mit dem Viewport Rect auszuführen.

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

Zum Beispiel dieses ...

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

... stellt ähnliche Viewportinformationen wie diese bereit...

<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 in ein beliebiges äußeres Viewport gebracht 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 messen, wo und wie viel Inhalt das FrameworkElement vorab generieren sollte, um möglicherweise den Viewport zu füllen, bevor er in die Ansicht scrollt.

Hinweis

Scrollen über direkte Eingaben wie Toucheingabe oder Stift wird vom System in einem separaten Prozess verarbeitet. Standardmäßig erfolgt der Bildlauf asynchron im UI-Thread. Steuerelemente, die Virtualisierung durchführen, müssen aufgrund der inhärenten Kosten für die Elementerstellung möglicherweise Inhalte frühzeitig 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 sehen möglicherweise Leerzeichen oder Stotter, beides Symptome, dass der UI-Thread nicht mit der Geschwindigkeit des Schwenkens Schritt halten kann.

Die Position des MaxViewports wird im Koordinatenbereich des FrameworkElements gemeldet. Wenn maxViewport in den Koordinatenbereich des ersten Viewports in der Vorgängerkette des FrameworkElement transformiert würde, würde sich das 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 null, aber kleiner als ActualWidth / ActualHeight ist, befindet sich das Element teilweise innerhalb des vom Benutzer sichtbaren Viewports. Wenn die Werte 0 (null) 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 noch nicht enthalten.

Formal ausgedrückt, sind diese Werte die Summe der absoluten Entfernung, die das FrameworkElement beim Erfüllen eines Aufrufs von StartBringIntoView übersetzt. Die Werte berücksichtigen nicht die Möglichkeit, dass ein Bildlaufsteuerelement 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 Vorgängerelemente berücksichtigt, berücksichtigt er nicht die Auswirkungen des Clippings (außer dem Clip des Elements, das von einem Bildlaufsteuerelement 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