Поделиться через


FrameworkElement.EffectiveViewportChanged Событие

Определение

Происходит при изменении действующего окна просмотраFrameworkElement.

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

Тип события

Требования к Windows

Семейство устройств
Windows 10, version 1809 (появилось в 10.0.17763.0)
API contract
Windows.Foundation.UniversalApiContract (появилось в v7.0)

Комментарии

Элемент управления прокруткой позволяет пользователю сдвигать или прокручивать содержимое, которое занимает больше места, чем доступно в пользовательском интерфейсе. Часть содержимого, которую видит пользователь, называется окном просмотра.

Событие EffectiveViewportChanged предоставляет несколько фрагментов информации:

  1. Фактический EffectiveViewport
  2. Вычисление для MaxViewport
  3. Скалярные значения для BringIntoViewDistanceX и BringIntoViewDistanceY

EffectiveViewport

EffectiveViewport — это пересечение всех известных параметров просмотра, содержащих FrameworkElement в поддереве. Если есть два или более окне просмотра (например, ScrollViewer , вложенный в другой ScrollViewer), которые не перекрываются, То EffectiveViewport является пустым прямоугольником.

Примечание

Чтобы окно просмотра элемента управления прокруткой было известно платформе, элемент управления должен ранее зарегистрировать его с помощью метода UIElement.RegisterAsScrollPort . Платформа использует clip зарегистрированного элемента при определении действующего окна просмотра.

При изменении окна просмотра элемента управления прокруткой необходимо вызвать его метод InvalidateViewport , чтобы сообщить платформе, что окно просмотра изменилось, и любой из его подэлеменов, которые прослушивают действующее окно просмотра, должны быть уведомлены об изменениях.

EffectiveViewport задается в пространстве координат FrameworkElement. Нет необходимости выполнять TransformToVisual с окном просмотра Rect.

В простом сценарии, где имеется ScrollViewer , содержащий один элемент, событие EffectiveViewportChanged предоставляет обновления окна просмотра, аналогичные событию ViewChanged . Main отличие заключается в том, что событие EffectiveViewportChanged возникает после этапа упорядочения макета.

Например, это ...

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

... предоставляет аналогичные сведения о окне просмотра, как это...

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

MaxViewport

MaxViewport похож на EffectiveViewport, но вместо того, чтобы представлять простое пересечение известных портов просмотра, он представляет пересечение портов просмотра, как если бы каждое из них было представлено в представлении любого внешнего окна просмотра. Результирующий rect представляет две вещи:

  1. максимальный размер, который может быть в EffectiveViewport (с учетом текущих размеров окна просмотра); и
  2. положение максимального эффективного окна просмотра относительно FrameworkElement.

Эти сведения можно использовать для оценки того, где и сколько содержимого должно быть предварительно создано FrameworkElement для потенциального заполнения окна просмотра , прежде чем оно будет прокручено в поле зрения.

Примечание

Прокрутка с помощью прямого ввода, например сенсорного ввода или пера, обрабатывается системой в отдельном процессе. По умолчанию прокрутка обрабатывается асинхронно до потока пользовательского интерфейса. Элементы управления, выполняющие виртуализацию, могут потребовать предварительного создания содержимого перед входом в окно просмотра из-за затрат на создание элемента.

Задержка подготовки всего содержимого до появления в представлении может привести к плохой прокрутке для пользователей. Пользователи могут видеть пустое пространство или заикание, что является признаком того, что поток пользовательского интерфейса не может идти в ногу со скоростью сдвига.

Положение MaxViewport указывается в пространстве координат FrameworkElement. Если maxViewport был преобразован в пространство координат первого окна просмотра в цепочке предков FrameworkElement, rect будет находиться в пределах этого первого окна просмотра.

BringIntoViewDistanceX и Y

Эти значения указывают, насколько близкоframeworkElement становится максимально видимым во всех его окнах просмотра.

Если значение больше нуля, но меньше , чем ActualWidth / ActualHeight , элемент частично находится в окне просмотра, видимом пользователем. Если значения равны нулю, FrameworkElement полностью находится в видимом для пользователя окне просмотра.

Совет

Это не гарантирует, что элемент будет видимым для пользователя, так как другие элементы с более высоким Z-порядком могут по-прежнему заключить FrameworkElement.

Более формально эти значения представляют собой сумму абсолютного расстояния, которое frameworkElement будет преобразовано при выполнении вызова StartBringIntoView. Значения не учитывают возможность отключения прокрутки для элемента управления прокруткой.

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

Поведение

  • Если действующее окно просмотра родительского и дочернего элементов изменится, родитель получит уведомление до дочернего элемента.
  • Событие возникает только для элементов в дереве пользовательского интерфейса, которые участвуют в макете. Например, если элемент не находится в динамическом дереве или свойство Visibility элемента или любого из его предков имеет значение Collapsed, это событие не будет вызываться.
  • Хотя действующее окно просмотра учитывает преобразования отрисовки для всех предков элементов, оно не учитывает эффекты обрезки (кроме клипа элемента, зарегистрированного элементом управления прокрутки в качестве окна просмотра).
  • Эффективное окно просмотра не учитывает окклюзию из-за того, что другие элементы имеют более высокий Z-порядок.

Применяется к

См. также раздел