此時我們嘗試一下打開物品欄,任意拖放一個物品到裝備欄中,OK,成功了。但是反過來,從裝備欄中將已裝備的東西拖到物品欄中卻報錯了,而且這個錯誤無法調試,後來經過反復嘗試,發現問題原來出在WrapPanel上,如果不使用WrapPanel,就算在兩個StackPanel之間拖放都不會存在任何問題;而從一個ListBox中將對象拖到另一個WrapPanel中時,卻會出現JS無法調試的錯誤;同樣的,我還曾嘗試使用一個PagedCollectionVIEw來對WrapPanel進行分頁,確實做到了,但是當將對象拖放到WrapPanel的第二頁時,同樣會報JS無法調試錯誤,基本肯定問題出來WrapPanel控件上,希望MS在未來的版本中能將這個實用的控件兼容性與功能完善好。沒辦法,都做到這個地步了,硬著頭皮也得寫完呀,看來只能自己去實現相應的事件功能模塊了。還是從ListBoxDragDropTarget的所有事件的理解著手。ListBoxDragDropTarget在拖放方面的事件真不少:DragEnter、DragLeave、DragOver、Drop、GiveFeedback、ItemDragCompleted、ItemDragStarting、ItemDroppedOnSource、ItemDroppedOnTarget、QueryContinueDrag,其中又可以化分為拖(Drag)和放(Drop)兩類,從字面意思上大家可以很容易理解,正常狀態下,從一個ListBox(這裡記做listBox1)往另外一個ListBox(記做listBox2)拖放控件,當鼠標在listBox1中的一個子控件上按住左鍵不放時,首先觸發的是listBox1的ItemDragStarting事件,然後會卡那麼一下(沒去看具體源碼,或許在執行遍歷,就算在4核的電腦上也同樣會卡一下,可見MS趕工的水平)完成抓取並觸發listBox1的ItemDragCompleted事件,如果是在自身listBox1中放下,則觸發listBox1的ItemDroppedOnSource事件,而如果在listBox2中放開,則先觸發listBox2的Drop事件,再最後觸發listBox1的ItemDroppedOnTarget事件。感覺上去還是比較混亂的,這個拖放做得真是。。。當然,在整個過程中還會觸發另外剩下的那幾個事件,字面上都很好理解,這裡就不細說了。
充分理解DragDrop事件的順序與原理後,我們制作物品欄與裝備欄之間的拖放就輕松多了,注冊相應的事件並對每個物品的類型進行判斷是否可以放置等即可(例如藥水是裝備不了的,而帽子是無法拖到鞋子上的):
物品欄與裝備欄之間除了通過拖放交互,在雙擊某個裝備時,應該實現同樣的裝/卸功能。因此,這裡我為QXIcon添加新的鼠標左鍵雙擊事件:public event MouseButtonEventHandler MouseLeftButtonDoubleClick;並通過如下代碼實現雙擊功能:
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();
}
};
嘿嘿,到此就大功告成了。當然,在換裝時還需要處理主角屬性變化等邏輯,且實際武器衣服的更換同樣會發生在主角身上(類似紙娃娃系統),這些內容在不同的游戲中處理方式不同,具體就不列舉了。下面是最後的效果圖,非常酷吧:
DragDropTarget拖放控件在目前來說限制太多,且支持的類型也很少,還存在BUG。但是它的出現著實讓人迷戀,在它還未完善前,大家如果打算使用相應功能,自行定義實現其實也是不錯的選擇,原理和ChildWindow有異曲同工之處,至少你可以很好的把握住從Drag到Drop整個流程到底誰被抓取,抓取源是什麼,放到了哪個目標源,替換的是哪個對象等等;而這些在目前我所用到的DragDropTarget控件中都很難去實現,或者說極不方便;畢竟這個開源工具集還在不斷的更新與完善中,Silverlight版本更新過快也對其有很大的影響。總來的說,一切美好東西的形成總是需要時間去磨練,期待更好,是我們每位開發者理想的追求。