FrameworkElement.EffectiveViewportChanged Événement

Définition

Se produit lorsque la fenêtre d’affichage effective de FrameworkElement change.

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

Type d'événement

Configuration requise pour Windows

Famille d’appareils
Windows 10, version 1809 (introduit dans 10.0.17763.0)
API contract
Windows.Foundation.UniversalApiContract (introduit dans v7.0)

Remarques

Un contrôle de défilement permet à l’utilisateur de parcourir du contenu qui occupe plus d’espace que celui disponible dans l’interface utilisateur. La partie du contenu que l’utilisateur voit est appelée fenêtre d’affichage.

L’événement EffectiveViewportChanged fournit plusieurs informations :

  1. EffectiveViewport réel
  2. Calcul pour maxViewport
  3. Valeurs scalaires pour BringIntoViewDistanceX et BringIntoViewDistanceY

EffectiveViewport

EffectiveViewport est l’intersection de toutes les fenêtres d’affichage connues qui contiennent l’élément FrameworkElement dans leur sous-arborescence. S’il existe au moins deux fenêtres d’affichage (par exemple, un ScrollViewer imbriqué à l’intérieur d’un autre ScrollViewer) qui ne se chevauchent pas, effectiveViewport est un rect vide.

Notes

Pour que la fenêtre d’affichage d’un contrôle de défilement soit connue de l’infrastructure, le contrôle doit l’avoir précédemment inscrite à l’aide de la méthode UIElement.RegisterAsScrollPort . L’infrastructure utilise le clip de l’élément inscrit lors de la détermination de la fenêtre d’affichage effective.

Lorsque la fenêtre d’affichage du contrôle de défilement change, il doit appeler sa méthode InvalidateViewport pour informer l’infrastructure que sa fenêtre d’affichage a changé et que tous ses sous-éléments qui écoutent la fenêtre d’affichage effective doivent être avertis des modifications.

EffectiveViewport est fourni dans l’espace de coordonnées de l’élément FrameworkElement. Il n’est pas nécessaire d’effectuer un TransformToVisual avec la fenêtre d’affichage Rect.

Dans un scénario simple où il existe un ScrollViewer qui contient un seul élément, l’événement EffectiveViewportChanged fournit des mises à jour de la fenêtre d’affichage similaires à l’événement ViewChanged . La main différence est que l’événement EffectiveViewportChanged est déclenché après la passe d’organisation de la disposition.

Par exemple, cette ...

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

... fournit des informations de fenêtre d’affichage similaires à celle-ci...

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

MaxViewport

MaxViewport est similaire à EffectiveViewport, mais au lieu de représenter une simple intersection des fenêtres d’affichage connues, il représente l’intersection des fenêtres d’affichage comme si chacune d’elles avait été mise en vue d’une fenêtre d’affichage externe. Le Rect résultant représente deux choses :

  1. la plus grande taille que peut être effectiveViewport (compte tenu des tailles de fenêtre d’affichage actuelles), et
  2. position de la fenêtre d’affichage effective maximale par rapport à FrameworkElement.

Ces informations peuvent être utilisées pour évaluer l’emplacement et la quantité de contenu que l’élément FrameworkElement doit prégénérer pour remplir potentiellement la fenêtre d’affichage avant de le faire défiler vers l’affichage.

Notes

Le défilement via une entrée directe telle que l’interaction tactile ou le stylet est géré par le système dans un processus distinct. Par défaut, le défilement est géré de manière asynchrone vers le thread d’interface utilisateur. Les contrôles qui effectuent la virtualisation peuvent avoir besoin de pré-générer du contenu bien avant d’entrer dans la fenêtre d’affichage en raison du coût inhérent de la création d’éléments.

Retarder la préparation de tout le contenu jusqu’à ce qu’il soit visible peut entraîner une mauvaise expérience de défilement pour les utilisateurs. Les utilisateurs peuvent voir des espaces vides ou des bégaiements, les deux symptômes du thread d’interface utilisateur ne pouvant pas suivre la vitesse du mouvement panoramique.

La position de MaxViewport est signalée dans l’espace de coordonnées de l’élément FrameworkElement. Si la fenêtre MaxViewport était transformée en espace de coordonnées de la première fenêtre d’affichage dans la chaîne d’ancêtres de FrameworkElement, la fenêtre Rect se trouverait dans les limites de cette première fenêtre d’affichage.

BringIntoViewDistanceX et Y

Ces valeurs indiquent à quel point FrameworkElement est proche de devenir visible au maximum dans toutes ses fenêtres d’affichage.

Si la valeur est supérieure à zéro, mais inférieure à actualWidth / ActualHeight , l’élément se trouve en partie dans la fenêtre d’affichage visible par l’utilisateur. Lorsque les valeurs sont égales à zéro, l’élément FrameworkElement se trouve entièrement dans la fenêtre d’affichage visible par l’utilisateur.

Conseil

Cela ne garantit pas que l’élément est visible par l’utilisateur, car d’autres éléments dont l’ordre Z est supérieur peuvent toujours être en cours d’insertion dans FrameworkElement.

Plus formellement, ces valeurs sont la somme de la distance absolue que l’élément FrameworkElement serait traduit lors d’un appel à StartBringIntoView. Les valeurs ne tient pas compte de la possibilité qu’un contrôle de défilement ait désactivé le défilement.

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

Comportement

  • Si la fenêtre d’affichage effective d’un parent et d’un enfant changent, le parent reçoit la notification avant l’enfant.
  • L’événement est déclenché uniquement pour les éléments de l’arborescence d’interface utilisateur qui participent à la disposition. Par exemple, si l’élément ne se trouve pas dans l’arborescence dynamique, ou si la propriété Visibility de l’élément ou de l’un de ses ancêtres est définie sur Collapsed, cet événement ne sera pas déclenché.
  • Bien que la fenêtre d’affichage effective prend en compte les transformations de rendu pour tous les ancêtres d’éléments, elle ne prend pas en compte les effets du découpage (autres que le découpage de l’élément inscrit par un contrôle de défilement comme fenêtre d’affichage).
  • La fenêtre d’affichage effective ne tient pas compte de l’occlusion en raison du fait que d’autres éléments ont un ordre Z plus élevé.

S’applique à

Voir aussi