首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

WPF 讓 ListBox 項目依序動態移動的 Behavior 實作

     編輯:關於.NET

專案需求:讓 ListBox 的項目在 Canvas 中從左向右依序滑入、滑出,並支援滑鼠點擊暫停/繼續。本文實作一個可重用的 CanvasItemBehavior 附加行為,透過附加屬性即可套用至任何 Canvas。

核心功能

  • 支援四種移動方向:左→右、右→左、上→下、下→上
  • 泡泡模式:項目隨機位置浮現
  • 自動偵測 ItemsSource 變更(新增/移除項目)
  • 可設定動畫持續時間 Duration
  • 滑鼠點擊項目可暫停/繼續動畫

使用方式

<Canvas local:CanvasItemBehavior.MoveMode="LeftToRight"
        local:CanvasItemBehavior.Duration="0:0:5">
    <ListBox ItemsSource="{Binding Items}" />
</Canvas>

關鍵實作細節

  1. 附加屬性定義:MoveMode、Duration、BubbleR、內部 Storyboard 儲存。
  2. Loaded 事件:掛載 INotifyCollectionChanged 監聽資料源變更,為每個 ListBoxItem 註冊 IsVisibleChanged 與 PreviewMouseDown。
  3. DispatcherTimer:每 50ms 檢查下一個隱藏項目,計算顯示間隔並啟動動畫。
  4. 動畫建立:根據 MoveMode 設定 DoubleAnimation 的 From/To(Canvas.Left 或 Canvas.Top),完成時隱藏項目並清理 Storyboard。

核心程式碼節錄

static void item_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    if ((bool)e.NewValue)
    {
        var item = sender as UIElement;
        if (GetStoryboard(item) == null)
        {
            var canvas = VisualTreeHelper.GetParent(item) as Canvas;
            var s = new Storyboard();
            var ani = new DoubleAnimation();
            Storyboard.SetTarget(ani, item);
            var mode = GetMoveMode(canvas);

            if ((int)mode < 3) // 水平
            {
                ani.From = -item.RenderSize.Width;
                ani.To = canvas.ActualWidth;
                ani.Duration = GetDuration(canvas) > TimeSpan.Zero ? GetDuration(canvas) 
                    : TimeSpan.FromSeconds(canvas.ActualWidth / 100);
                Storyboard.SetTargetProperty(ani, new PropertyPath(Canvas.LeftProperty));
            }
            else // 垂直
            {
                ani.From = -item.RenderSize.Height;
                ani.To = canvas.ActualHeight;
                ani.Duration = GetDuration(canvas) > TimeSpan.Zero ? GetDuration(canvas)
                    : TimeSpan.FromSeconds(canvas.ActualHeight / 100);
                Storyboard.SetTargetProperty(ani, new PropertyPath(Canvas.TopProperty));
            }

            s.Children.Add(ani);
            s.Completed += (ss, ee) => { item.Visibility = Visibility.Hidden; SetStoryboard(item, null); };
            SetStoryboard(item, s);
            s.Begin();
        }
    }
}

優勢

  • 零程式碼後置,純 XAML 宣告式套用
  • 支援資料繫結、虛擬化、動態資料源
  • 效能優於傳統逐項建立動畫方式

完整原始碼包含 MoveOrientaion 列舉、VisualHelper 輔助類別,已整理為可直接引用的類別庫。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved