using Avalonia.Animation.Easings; using Avalonia.Animation; using Avalonia; using Avalonia.Controls; using Avalonia.Xaml.Interactivity; using Irihi.Avalonia.Shared.Helpers; using Avalonia.Controls.Presenters; using Avalonia.Data; using Avalonia.Media; using Avalonia.Styling; namespace Plugin.Cowain.Wcs.Controls; public class GridColumnAnimationBehavior : Behavior { private IDisposable? _columnSubscription; public static readonly StyledProperty GridColumnProperty = AvaloniaProperty.Register( nameof(GridColumn), defaultBindingMode: BindingMode.TwoWay); public int GridColumn { get => GetValue(GridColumnProperty); set => SetValue(GridColumnProperty, value); } protected override void OnAttached() { base.OnAttached(); if (AssociatedObject is not null) { // 开始监听布局更新或直接触发初始动画 AssociatedObject.AttachedToVisualTree += HandleAttached; } } protected override void OnDetaching() { if (AssociatedObject is not null) { AssociatedObject.AttachedToVisualTree -= HandleAttached; } _columnSubscription?.Dispose(); base.OnDetaching(); } private void HandleAttached(object? sender, VisualTreeAttachmentEventArgs e) { if (AssociatedObject is Grid grid && grid.Parent is ContentPresenter contentPresenter) { // 使用绑定监听Grid.Column变化 _columnSubscription = contentPresenter.GetObservable(Grid.ColumnProperty) .Subscribe(column => { if (column != GridColumn) { AnimateColumnChange(grid, column, GridColumn); } }); } } private void AnimateColumnChange(Grid grid, int fromColumn, int toColumn) { var contentPresenter = grid.Parent as ContentPresenter; if (contentPresenter == null) return; // 创建水平移动动画 var transform = new TranslateTransform(); contentPresenter.RenderTransform = transform; var _animation = new Animation { Duration = TimeSpan.FromSeconds(0.3), Easing = new CubicEaseInOut(), Children = { new KeyFrame { Cue = new Cue(0d), Setters = { new Setter { Property = TranslateTransform.XProperty, Value = fromColumn * -grid.ColumnDefinitions[fromColumn].ActualWidth } } }, new KeyFrame { Cue = new Cue(1d), Setters = { new Setter { Property = TranslateTransform.XProperty, Value = toColumn * -grid.ColumnDefinitions[toColumn].ActualWidth } } } } }; _animation.RunAsync(contentPresenter); } }