CI / Go Backend (push) Canceled after 0s
初始化 monorepo: Go后端(7微服务) + Unity客户端(9模块) + 启动器 HTML5原型: Three.js 3D体素世界, Perlin噪声地形, 原版材质, 22种方块 Minecraft创造模式背包: 双栏布局, 拖拽移动物品, 方向性元件引脚 AI助搭策划文档 + 客户端/服务端骨架 + Docker Compose + CI
74 lines
2.1 KiB
C#
74 lines
2.1 KiB
C#
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Media;
|
|
using Microsoft.Xaml.Behaviors;
|
|
|
|
namespace PCL;
|
|
|
|
internal static class LazyLoader
|
|
{
|
|
public static void EnableLazyLoad(this FrameworkElement element, Action action)
|
|
{
|
|
var behavior = new LazyLoadBehavior();
|
|
behavior.Action = action;
|
|
Interaction.GetBehaviors(element).Add(behavior);
|
|
}
|
|
}
|
|
|
|
public class LazyLoadBehavior : Behavior<FrameworkElement>
|
|
{
|
|
public static readonly DependencyProperty ActionProperty = DependencyProperty.Register(nameof(Action),
|
|
typeof(Action), typeof(LazyLoadBehavior), new PropertyMetadata(null));
|
|
|
|
public Action Action
|
|
{
|
|
get => (Action)GetValue(ActionProperty);
|
|
set => SetValue(ActionProperty, value);
|
|
}
|
|
|
|
protected override void OnAttached()
|
|
{
|
|
base.OnAttached();
|
|
AssociatedObject.LayoutUpdated += OnLayoutUpdated;
|
|
}
|
|
|
|
protected override void OnDetaching()
|
|
{
|
|
AssociatedObject.LayoutUpdated -= OnLayoutUpdated;
|
|
base.OnDetaching();
|
|
}
|
|
|
|
private void OnLayoutUpdated(object sender, EventArgs e)
|
|
{
|
|
var element = AssociatedObject;
|
|
if (element is null || element.RenderSize.Width < double.Epsilon || !element.IsVisible)
|
|
return;
|
|
|
|
var scrollViewer = FindParentScrollViewer(element);
|
|
if (scrollViewer is null)
|
|
return;
|
|
|
|
var elementBounds = element.TransformToAncestor(scrollViewer)
|
|
.TransformBounds(new Rect(new Point(0d, 0d), element.RenderSize));
|
|
var viewport = new Rect(0d, 0d, scrollViewer.ViewportWidth, scrollViewer.ViewportHeight);
|
|
|
|
if (!viewport.IntersectsWith(elementBounds))
|
|
return;
|
|
|
|
Action?.Invoke();
|
|
// 仅执行一次
|
|
element.LayoutUpdated -= OnLayoutUpdated;
|
|
}
|
|
|
|
private static ScrollViewer FindParentScrollViewer(DependencyObject d)
|
|
{
|
|
for (var current = d; current is not null; current = VisualTreeHelper.GetParent(current))
|
|
{
|
|
if (current is ScrollViewer scrollViewer)
|
|
return scrollViewer;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|