LazyLoadBehavior.vb 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. Public Class LazyLoadBehavior
  2. ''' <summary>
  3. ''' 指定首次进入 ScrollViewer 的可视范围时执行的操作。
  4. ''' </summary>
  5. Public Shared Sub OnFirstEnterScrollViewerViewport(obj As DependencyObject, value As Action)
  6. obj.SetValue(IsInViewportProperty, value)
  7. End Sub
  8. Private Shared ReadOnly IsInViewportProperty As DependencyProperty =
  9. DependencyProperty.RegisterAttached("IsInViewport", GetType(Action), GetType(LazyLoadBehavior),
  10. New PropertyMetadata(Nothing, AddressOf OnIsInViewportChanged))
  11. Private Shared Sub OnIsInViewportChanged(d As DependencyObject, e As DependencyPropertyChangedEventArgs)
  12. Dim Element = TryCast(d, FrameworkElement)
  13. If Element Is Nothing OrElse e.NewValue Is Nothing Then Return
  14. Dim Handled As Boolean = False
  15. Dim Handler As EventHandler =
  16. Sub()
  17. If Handled Then Return
  18. '判断元素是否可见
  19. If Element.RenderSize.Width < Double.Epsilon Then Return
  20. If Not Element.IsVisible Then Return
  21. '判断是否在 ScrollViewer 的可视区域内
  22. Dim Scroll = FindParentScrollViewer(Element)
  23. If Scroll Is Nothing Then Return
  24. If Not New Rect(0, 0, Scroll.ViewportWidth, Scroll.ViewportHeight).IntersectsWith(
  25. Element.TransformToAncestor(Scroll).TransformBounds(New Rect(New Point(0, 0), Element.RenderSize))) Then Return
  26. '执行
  27. Handled = True
  28. CType(e.NewValue, Action).Invoke()
  29. RemoveHandler Element.LayoutUpdated, Handler
  30. End Sub
  31. AddHandler Element.LayoutUpdated, Handler
  32. End Sub
  33. Private Shared Function FindParentScrollViewer(d As DependencyObject) As ScrollViewer
  34. While d IsNot Nothing
  35. If TypeOf d Is ScrollViewer Then Return CType(d, ScrollViewer)
  36. d = VisualTreeHelper.GetParent(d)
  37. End While
  38. Return Nothing
  39. End Function
  40. End Class