Files
MRCC/launcher/PCL-CE/Plain Craft Launcher 2/Controls/Behaviors/LazyLoadBehavior.cs
T
xyou f70b061d1a
CI / Go Backend (push) Canceled after 0s
feat: 项目初始化 + 3D方块世界原型 + AI助搭系统
初始化 monorepo: Go后端(7微服务) + Unity客户端(9模块) + 启动器

HTML5原型: Three.js 3D体素世界, Perlin噪声地形, 原版材质, 22种方块

Minecraft创造模式背包: 双栏布局, 拖拽移动物品, 方向性元件引脚

AI助搭策划文档 + 客户端/服务端骨架 + Docker Compose + CI
2026-08-08 14:07:56 +08:00

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