FrameworkElement.EffectiveViewportChanged 事件
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
發生于 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)
事件類型
備註
捲動控制項可讓使用者移動流覽/捲動佔用超過 UI 中可用空間的內容。 使用者看到的內容部分稱為 檢視區。
EffectiveViewportChanged 事件提供多個資訊片段:
EffectiveViewport
EffectiveViewport是包含其子樹狀結構中FrameworkElement的所有已知檢視區交集。 例如,如果有兩個以上的檢視區 (,另一個 ScrollViewer 內巢狀的 ScrollViewer) 不會重迭,則 EffectiveViewport 是空的 Rect。
注意
若要讓架構 知道 捲動控制項的檢視區,控制項先前必須使用 UIElement.RegisterAsScrollPort 方法註冊它。 架構會在判斷有效的檢視區時,使用已註冊專案的 Clip 。
當捲動控制項的檢視區變更時,必須叫用 其 InvalidateViewport 方法,通知架構其檢視區已變更,以及接聽有效檢視區的任何子項目都必須收到變更通知。
EffectiveViewport是在FrameworkElement的座標空間中提供。 不需要使用檢視區Rect執行TransformToVisual。
在包含單一元素的 ScrollViewer 簡單案例中,EffectiveViewportChanged 事件會提供類似 ViewChanged 事件的檢視區更新。 主要差異在於 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 代表兩件事:
- 如果目前的檢視區大小) ,EffectiveViewport 可以 (的大小上限,以及
- 相對於 FrameworkElement的最大有效檢視區位置。
這項資訊可用來測量 FrameworkElement 在捲動到檢視 區之前 ,應該預先產生多少內容來填入檢視區。
注意
透過直接輸入捲動,例如觸控或手寫筆,是由系統在不同的進程中處理。 根據預設,捲動會以非同步方式處理至 UI 執行緒。 執行虛擬化的控制項可能需要在輸入檢視區之前預先產生內容,因為元素建立的固有成本。
延遲所有內容準備,直到進入檢視為止,可能會導致使用者的捲動體驗不佳。 使用者可能會看到空白或雜亂,UI 執行緒的兩個徵兆都無法跟上移動流覽的速度。
MaxViewport的位置會在FrameworkElement的座標空間中報告。 如果 MaxViewport 已轉換成 FrameworkElement上階鏈中第一個檢視區的座標空間, Rect 會位於該第一個檢視區的範圍內。
BringIntoViewDistanceX 和 Y
這些值表示 FrameworkElement 在其所有檢視區中,要以最大方式顯示FrameworkElement。
如果值大於零,但小於ActualWidth / ActualHeight,則元素會部分位於使用者可見檢視區內。 當值為零時, FrameworkElement 會完全在使用者可見檢視區內。
提示
這不保證使用者可以看到元素,因為具有較高 Z 順序的其他元素仍可能會遮蔽 FrameworkElement。
更正式表示,這些值是滿足StartBringIntoView呼叫時,FrameworkElement將轉譯的絕對距離總和。 這些值不會考慮捲動控制項已停用捲動的可能性。
<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;
}
行為
- 如果父系和子系的有效檢視區都變更,父系將會在子系之前收到通知。
- 事件只會針對參與版面配置的 UI 樹狀結構中的元素引發。 例如,如果專案不在即時樹狀結構中,或元素的 Visibility 屬性或其任何上階設定為 Collapsed,則不會引發此事件。
- 雖然有效的檢視區會考慮所有元素上階的轉譯轉換,但不會考慮裁剪 (除了捲動控制項所註冊之元素的裁剪效果之外,將其檢視區) 。
- 有效的檢視區不會考慮遮蔽,因為其他元素的 Z 順序較高。