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

C# 開發 WPF/Silverlight 動畫與遊戲教學 (45-3):物品欄與裝備欄拖放系統完結篇

     編輯:關於C語言

物品/裝備欄雙向拖放最終解決方案:繞過 WrapPanel Bug 自行實現

Toolkit ListBoxDragDropTarget 配合 WrapPanel 存在嚴重 JS 無法除錯錯誤,最終決定自行實現拖放邏輯核心模組。

一、WrapPanel 相容性問題分析

  • 症狀:從 ListBox 拖放到 WrapPanel、WrapPanel 分頁切換時拖放均觸發 JS 錯誤
  • 根因:WrapPanel 內部實現缺陷,微軟後續版本未修復
  • 決策:放棄 Toolkit 拖放框架,自行實現核心事件流程

二、拖放事件流程深度解析

ListBoxDragDropTarget 事件順序:

  1. ItemDragStarting (源 ListBox) → 卡頓 (疑似遍歷開銷)
  2. ItemDragCompleted (源 ListBox)
  3. 放置目標判斷:
    • 源內放置 → ItemDroppedOnSource
    • 目標放置 → Drop (目標) → ItemDroppedOnTarget (源)

其他事件:DragEnter、DragLeave、DragOver、GiveFeedback、QueryContinueDrag。

三、自行實現核心邏輯

註冊標準拖放事件,針對物品類型驗證 (藥水不可裝備、部位限制等):

物品裝備欄拖放效果
圖 1:物品欄與裝備欄雙向拖放運作截圖

四、雙擊裝備/卸下功能:QXIcon 新增 DoubleClick 事件

public event MouseButtonEventHandler MouseLeftButtonDoubleClick;

DispatcherTimer doubleClickTimer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(250) };
doubleClickTimer.Tick += (s, e) => { doubleClickTimer.Stop(); };

this.MouseLeftButtonDown += (s, e) => {
    if (doubleClickTimer.IsEnabled) {
        doubleClickTimer.Stop();
        if (MouseLeftButtonDoubleClick != null) MouseLeftButtonDoubleClick(s, e);
    } else {
        doubleClickTimer.Start();
    }
};

250ms 判定窗口,符合系統雙擊速度設定。

五、最終效果與總結

完整裝備系統界面
圖 2:物品/裝備欄完整系統最終效果

心得:Toolkit 拖放框架限制多、Bug 多、類型支援少。自行實現雖費時但可完全掌控流程 (誰被抓取、抓取源、放置目標、替換對象),且原理與 ChildWindow 實現異曲同工。期待官方框架成熟,但現階段自研是務實選擇。

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