FrameworkElement.EffectiveViewportChanged Evento

Definizione

Si verifica quando il viewport efficace di FrameworkElement cambia.

// 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) 

Tipo evento

Requisiti Windows

Famiglia di dispositivi
Windows 10, version 1809 (è stato introdotto in 10.0.17763.0)
API contract
Windows.Foundation.UniversalApiContract (è stato introdotto in v7.0)

Commenti

Un controllo di scorrimento consente all'utente di scorrere/scorrere il contenuto che occupa più spazio di quanto sia disponibile nell'interfaccia utente. La parte del contenuto visualizzato dall'utente è denominata viewport.

L'evento EffectiveViewportChanged fornisce più informazioni:

  1. Effettivo EffectiveViewport
  2. Calcolo per MaxViewport
  3. Valori scalari per BringIntoViewDistanceX e BringIntoViewDistanceY

EffectiveViewport

EffectiveViewport è l'intersezione di tutti i viewport noti che contengono FrameworkElement nel sotto-albero. Se sono presenti due o più viewport (ad esempio, uno ScrollViewer annidato all'interno di un altro ScrollViewer) che non si sovrappongono, il valore di EffectiveViewport è un oggetto Rect vuoto.

Nota

Per essere noti al framework, il controllo deve essere registrato in precedenza usando il metodo UIElement.RegisterAsScrollPort . Il framework usa clip dell'elemento registrato quando si determina il viewport efficace.

Quando il riquadro di visualizzazione del controllo di scorrimento cambia, deve richiamare il metodo InvalidateViewport per informare il framework che il relativo riquadro di visualizzazione è stato modificato e uno dei relativi sottoelementi che ascoltano il viewport effettivo deve ricevere una notifica delle modifiche.

Il valore di EffectiveViewport viene fornito nello spazio di coordinate di FrameworkElement. Non è necessario eseguire un oggetto TransformToVisual con il riquadro di visualizzazione Rect.

In uno scenario semplice in cui è presente un oggetto ScrollViewer contenente un singolo elemento, l'evento EffectiveViewportChanged fornisce aggiornamenti del riquadro di visualizzazione simili all'evento ViewChanged . La differenza principale è che l'evento EffectiveViewportChanged viene generato dopo il passaggio di layout.

Ad esempio, questo ...

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

... fornisce informazioni simili sul viewport in questo modo...

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

MaxViewport

MaxViewport è simile a EffectiveViewport, ma invece di rappresentare un'intersezione semplice dei viewport noti, rappresenta l'intersezione dei viewport come se ognuno fosse stato portato in vista di qualsiasi viewport esterno. Il rect risultante rappresenta due elementi:

  1. le dimensioni più grandi che è possibile eseguire con EffectiveViewport (in base alle dimensioni correnti del riquadro di visualizzazione) e
  2. posizione del viewport massimo effettivo relativo a FrameworkElement.

Queste informazioni possono essere usate per misurare la posizione e la quantità di contenuto che FrameworkElement deve generare per riempire potenzialmente il riquadro di visualizzazione prima di scorrere nella visualizzazione.

Nota

Lo scorrimento tramite input diretto, ad esempio tocco o penna, viene gestito dal sistema in un processo separato. Per impostazione predefinita, lo scorrimento viene gestito in modo asincrono al thread dell'interfaccia utente. I controlli che eseguono la virtualizzazione potrebbero dover pre-generare contenuto in anticipo per immettere il riquadro di visualizzazione a causa del costo intrinseco della creazione di elementi.

Ritardando la preparazione di tutti i contenuti fino a quando la visualizzazione non può portare a un'esperienza di scorrimento scarsa per gli utenti. Gli utenti possono visualizzare spazi vuoti o stub, entrambi i sintomi del thread dell'interfaccia utente non sono in grado di mantenere la velocità di panoramica.

La posizione di MaxViewport viene segnalata nello spazio di coordinate di FrameworkElement. Se il MaxViewport è stato trasformato nello spazio di coordinate del primo viewport nella catena di predecessori di FrameworkElement, il rect si trova entro i limiti del primo viewport.

BringIntoViewDistanceX e Y

Questi valori indicano come chiudereFrameworkElement per diventare massimamente visibili in tutti i relativi viewport.

Se il valore è maggiore di zero, ma minore di ActualWidth / ActualHeight , l'elemento è parzialmente all'interno del viewport visibile dall'utente. Quando i valori sono zero, FrameworkElement è completamente all'interno del viewport visibile dall'utente.

Suggerimento

Ciò non garantisce che l'elemento sia visibile all'utente poiché altri elementi con un ordine Z superiore potrebbero comunque essere occludati in FrameworkElement.

Dichiarati più formalmente, questi valori sono la somma della distanza assoluta che frameworkElement verrebbe tradotta quando soddisfa una chiamata a StartBringIntoView. I valori non consentono di tenere conto della possibilità che un controllo di scorrimento abbia disabilitato lo scorrimento.

<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;
}

Comportamento

  • Se il viewport effettivo di un elemento padre e figlio cambiano entrambi, l'elemento padre riceverà la notifica prima dell'elemento figlio.
  • L'evento viene generato solo per gli elementi nell'albero dell'interfaccia utente che partecipano al layout. Ad esempio, se l'elemento non si trova nell'albero attivo o se la proprietà Visibility dell'elemento o uno dei relativi predecessori è impostata su Compressd, questo evento non verrà generato.
  • Anche se il viewport efficace tiene conto delle trasformazioni di rendering per tutti gli elementi predecessori, non considera gli effetti del ritaglio (diversamente dalla clip dell'elemento registrato da un controllo di scorrimento come viewport).
  • Il viewport efficace non tiene conto dell'occlusione a causa di altri elementi con un ordine Z superiore.

Si applica a

Vedi anche