WPF應用中,控制元件本身也可以通過實現事件程式碼實現拖動的處理,不過如果我們使用GongSolutions.WPF.DragDrop來處理,事情會變得更加簡單輕鬆,它支援很多控制元件的拖動處理,如ListBox, ListView, TreeView, DataGrid等源自ItemsControl的控制元件,本篇隨筆介紹在工作流模組中拖動TreeView和DataGrid列表實現流程順序的調整處理。
控制元件的GitHub地址:https://github.com/punker76/gong-wpf-dragdrop
使用GongSolutions.WPF.DragDrop比較簡單,和其他類似的做法差不多,首先在Nugget找到並新增對應的控制元件參照,如下所示。
新增完成相關的參照後,我們在需要使用的XAML頁面中新增對應的名稱空間,如下程式碼上所示。
xmlns:dd="urn:gong-wpf-dragdrop"
主要使用框架依賴屬性:
dd:DragDrop.IsDragSource="True"//是否作為拖拽源
dd:DragDrop.IsDropTarget="False"//是否作為投遞目標
dd:DragDrop.UseDefaultDragAdorner="True"//使用預設的拖拽裝飾器
dd:DragDrop.UseDefaultEffectDataTemplate="True"//使用預設的陰影資料模板
dd:DragDrop.EffectMoveAdornerTemplate//指定移動時的陰影裝飾器模板
dd:DragDrop.DropHandler="{Binding MyDropHandler}"//投下時執行處理器
不過我們一般使用其中的三項就可以了,如下程式碼所示,是基於MVVM的模型繫結
dd:DragDrop.DropHandler="{Binding ViewModel}"
dd:DragDrop.IsDragSource="True"
dd:DragDrop.IsDropTarget="True"
如下列表的介面,就是設定了拖動的事件處理效果
拖動調整後,我們直觀的提示一下介面即可,如下所示。
前面我們看到程式碼中有 dd:DragDrop.DropHandler="{Binding ViewModel}" ,這個檢視模型裡面就是包含了拖動處理的事件的,我們看看它的定義。
首先檢視模型需要實現介面IDropTarget,以便處理拖動後的順序修改邏輯,它的介面定義如下所示。
我們的檢視模型實現實現IDropTarget介面,包含了兩個Over和Drop的方法的實現,如下程式碼所示。
主要就是後臺對拖動的響應,以便更新後端的記錄順序,我們通過Seq的順序來調整即可。
上面介紹的是對於TreeViw控制元件的處理,對於DataGrid的處理方法,也是用類似的方式來實現即可。
其中它的XAML介面程式碼如下所示。
<DataGrid x:Name="grid" dd:DragDrop.DropHandler="{Binding ViewModel}" dd:DragDrop.IsDragSource="True" dd:DragDrop.IsDropTarget="True" dd:DragDrop.UseDefaultDragAdorner="True" hc:DataGridAttach.ShowRowNumber="True" AutoGenerateColumns="False" HeadersVisibility="All" IsReadOnly="True" ItemsSource="{Binding ViewModel.Items}" MouseDoubleClick="DataGrid_MouseDoubleClick" RowHeaderWidth="60" SelectionChanged="DataGrid_SelectionChanged" SelectionMode="Extended">
同樣我們可以看到的處理方式類似做法,後端頁面程式碼也是實現拖動的順序處理即可,檢視模型實現實現IDropTarget介面,如下是檢視模型程式碼實現。
#region 控制元件拖放處理 void IDropTarget.DragOver(IDropInfo dropInfo) { var sourceItem = dropInfo.Data as FormFlowInfo; var targetItem = dropInfo.TargetItem as FormFlowInfo; if (sourceItem != null && targetItem != null)// && targetItem.CanAcceptChildren) { dropInfo.DropTargetAdorner = DropTargetAdorners.Highlight; dropInfo.Effects = DragDropEffects.Copy; } } async void IDropTarget.Drop(IDropInfo dropInfo) { var sourceItem = (FormFlowInfo)dropInfo.Data; var targetItem = (FormFlowInfo)dropInfo.TargetItem; string dragMenuId = sourceItem.Id; string dropMenuId = targetItem.Id; try { if (!dragMenuId.IsNullOrEmpty() && !dropMenuId.IsNullOrEmpty()) { await BLLFactory<IFormFlowService>.Instance.UpdateTwoSeq(dragMenuId, dropMenuId); await GetData(); GrowlUtil.ShowInfo("已調整了步驟順序"); } } catch (Exception ex) { LogTextHelper.Error(ex); GrowlUtil.ShowError(ex.Message); } } #endregion
以上就是在WPF應用中使用GongSolutions.WPF.DragDrop實現列表集合控制元件的拖動處理,它在其他各型別列表集合控制元件中使用都是類似的方式,因此比較好用,而且實現的效果也比較不錯,強烈推薦。