FrameworkElement.EffectiveViewportChanged Kejadian

Definisi

Terjadi ketika viewport efektifFrameworkElement berubah.

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

Jenis Acara

Persyaratan Windows

Rangkaian perangkat
Windows 10, version 1809 (diperkenalkan dalam 10.0.17763.0)
API contract
Windows.Foundation.UniversalApiContract (diperkenalkan dalam v7.0)

Keterangan

Kontrol gulir memungkinkan pengguna untuk menggeser/menggulir konten yang membutuhkan lebih banyak ruang daripada yang tersedia di UI. Bagian konten yang dilihat pengguna disebut viewport.

Peristiwa EffectiveViewportChanged menyediakan beberapa informasi:

  1. EffectiveViewport yang sebenarnya
  2. Perhitungan untuk MaxViewport
  3. Nilai skalar untuk BringIntoViewDistanceX dan BringIntoViewDistanceY

EffectiveViewport

EffectiveViewport adalah persimpangan dari semua viewport yang diketahui yang berisi FrameworkElement di sub-pohon mereka. Jika ada dua viewport atau lebih (misalnya, ScrollViewer yang berlapis di dalam ScrollViewer lain) yang tidak tumpang tindih, maka EffectiveViewport adalah Rect kosong.

Catatan

Agar viewport kontrol gulir diketahui oleh kerangka kerja, kontrol sebelumnya harus mendaftarkannya menggunakan metode UIElement.RegisterAsScrollPort . Kerangka kerja menggunakan Klip elemen terdaftar saat menentukan viewport yang efektif.

Ketika viewport kontrol gulir berubah, ia harus memanggil metode InvalidateViewport untuk menginformasikan kerangka kerja bahwa viewport-nya telah berubah dan salah satu sub-elemennya yang mendengarkan viewport yang efektif perlu diberi tahu tentang perubahan.

EffectiveViewport diberikan di ruang koordinat FrameworkElement. Tidak perlu melakukan TransformToVisual dengan viewport Rect.

Dalam skenario sederhana di mana ada ScrollViewer yang berisi satu elemen, peristiwa EffectiveViewportChanged menyediakan pembaruan viewport yang mirip dengan peristiwa ViewChanged . Perbedaan utamanya adalah bahwa peristiwa EffectiveViewportChanged dinaikkan setelah kode tata letak.

Misalnya, ini ...

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

... menyediakan informasi viewport serupa seperti ini...

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

MaxViewport

MaxViewport mirip dengan EffectiveViewport, tetapi alih-alih mewakili persimpangan sederhana dari viewport yang diketahui, itu mewakili persimpangan viewport seolah-olah masing-masing telah dibawa ke tampilan luar apa pun. Rect yang dihasilkan mewakili dua hal:

  1. ukuran terbesar yang dapat dilakukan oleh EffectiveViewport (mengingat ukuran viewport saat ini), dan
  2. posisi viewport efektif maksimum relatif terhadap FrameworkElement.

Informasi ini dapat digunakan untuk mengukur di mana dan berapa banyak konten yang harus dibuat sebelumnya oleh FrameworkElement untuk berpotensi mengisi viewport sebelum digulir ke tampilan.

Catatan

Menggulir melalui input langsung seperti sentuhan atau pena ditangani oleh sistem dalam proses terpisah. Secara default, pengguliran ditangani secara asinkron ke utas UI. Kontrol yang melakukan virtualisasi mungkin perlu menghasilkan konten terlebih dahulu sebelum memasuki viewport karena biaya pembuatan elemen yang melekat.

Menunda semua persiapan konten hingga terlihat dapat menyebabkan pengalaman gulir yang buruk bagi pengguna. Pengguna mungkin melihat ruang kosong atau gagap, kedua gejala utas UI tidak dapat mengikuti kecepatan panning.

Posisi MaxViewport dilaporkan di ruang koordinat FrameworkElement. Jika MaxViewport diubah ke ruang koordinat viewport pertama dalam rantai leluhur FrameworkElement, Rect akan berada dalam batas viewport pertama tersebut.

BringIntoViewDistanceX dan Y

Nilai-nilai ini menunjukkan seberapa dekatFrameworkElement menjadi terlihat secara maksimal di semua viewport-nya.

Jika nilainya lebih besar dari nol, tetapi kurang dari ActualWidth / ActualHeight , maka elemen sebagian berada dalam viewport yang terlihat pengguna. Ketika nilainya nol, maka FrameworkElement sepenuhnya berada dalam viewport yang terlihat pengguna.

Tip

Ini tidak menjamin bahwa elemen terlihat oleh pengguna karena elemen lain dengan urutan Z yang lebih tinggi mungkin masih menempati FrameworkElement.

Dinyatakan lebih resmi, nilai-nilai ini adalah jumlah jarak absolut yang akan diterjemahkan frameworkElement saat memenuhi panggilan ke StartBringIntoView. Nilai tidak mempertimbangan kemungkinan bahwa kontrol gulir telah dinonaktifkan.

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

Aktivitas

  • Jika viewport efektif induk dan anak berubah, induk akan menerima pemberitahuan sebelum turunan.
  • Peristiwa ini hanya dinaikkan untuk elemen di pohon UI yang berpartisipasi dalam tata letak. Misalnya, jika elemen tidak berada di pohon langsung, atau jika properti Visibilitas elemen atau salah satu leluhurnya diatur ke Diciutkan, peristiwa ini tidak akan dinaikkan.
  • Meskipun viewport yang efektif memperkirakan transformasi render untuk semua elemen leluhur, itu tidak mempertimbangkan efek kliping (selain klip elemen yang didaftarkan oleh kontrol gulir sebagai viewport-nya).
  • Viewport yang efektif tidak memperhitungkan oklusi karena elemen lain memiliki urutan Z yang lebih tinggi.

Berlaku untuk

Lihat juga