DevExpress WPF 15.2代码示例:如何为网格添加DragAndDrop功能
作者: 来源:DevExpress 浏览:Loading...次 发布时间:2016-01-11 评论:0条
本来带有DataControlDetailDescriptor的detail网格是不支持拖放操作的,所以要实现这个功能,首先我们创建一个GridDragDropManager class,然后覆盖CalcDraggingRows method去获取一个选中的行。然后,应用到GridDragDropManager's DragOver and Drop。当鼠标拖动时,计算要插入选中行的位置。
代码:C# 版本:15.2.4
using DevExpress.Mvvm.UI; using DevExpress.Xpf.Core.Native; using DevExpress.Xpf.Grid; using DevExpress.Xpf.Grid.DragDrop; using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; using System.Windows.Media; using System.Windows.Threading; namespace DragAndDropExample { class CustomGridDragAndDrop : GridDragDropManager { public TableView TableView; public RowControl SourceRow; public CustomGridDragAndDrop() { Drop += CustomGridDragAndDrop_Drop; DragOver += CustomGridDragAndDrop_DragOver; } void CustomGridDragAndDrop_DragOver(object sender, GridDragOverEventArgs e) { var result = VisualTreeHelper.HitTest(this.View, Mouse.GetPosition(View)); if (result != null && result.VisualHit != null) { var hitRow = LayoutTreeHelper.GetVisualParents(HitElement).Where(row => row is GroupGridRow || row is RowControl).FirstOrDefault() as FrameworkElement; if (hitRow != null) { var rowData = hitRow.DataContext as RowData; e.AllowDrop = Equals(rowData.Row.GetType(), e.DraggedRows[0].GetType()); e.Handled = true; } else { e.AllowDrop = false; e.Handled = true; } } } protected override bool CanStartDrag(MouseButtonEventArgs e) { SourceRow = LayoutTreeHelper.GetVisualParents(e.OriginalSource as DependencyObject).Where(row => row is RowControl).FirstOrDefault() as RowControl; return base.CanStartDrag(e); } void CustomGridDragAndDrop_Drop(object sender, GridDropEventArgs e) { if (TableView != null) { DropRow(e); TableView = null; e.Handled = true; } } protected override IList CalcDraggingRows(DevExpress.Xpf.Core.IndependentMouseEventArgs e) { if (SourceRow != null) { var rowData = SourceRow.DataContext as RowData; TableView = rowData.View as TableView; return new List<object> { rowData.Row }; } else return null; } public void DropRow(GridDropEventArgs args) { var currentRow = LayoutTreeHelper.GetVisualParents(HitElement).Where(row => row is GroupGridRow || row is RowControl).FirstOrDefault() as FrameworkElement; var rowData = currentRow.DataContext as RowData; var tableSource = TableView.Grid.ItemsSource as IList; var dataView = rowData.View as TableView; var dataSource = dataView.Grid.ItemsSource as IList; var rowIndex = dataView.Grid.GetListIndexByRowHandle(args.TargetRowHandle); var draggingRow = DraggingRows[0]; if (dataSource == null || dataSource[0].GetType() != draggingRow.GetType() || dataSource.Count == 0 || draggingRow == rowData.Row) { return; } if (Equals(tableSource, dataSource) && tableSource.IndexOf(DraggingRows[0]) <= rowIndex) { rowIndex--; } tableSource.Remove(DraggingRows[0]); if (!dataView.Grid.IsGrouped) { if (args.DropTargetType == DropTargetType.InsertRowsBefore) { dataSource.Insert(rowIndex, draggingRow); } else if (args.DropTargetType == DropTargetType.InsertRowsAfter) { dataSource.Insert(Math.Min(rowIndex + 1, dataSource.Count), draggingRow); } else { if (Mouse.GetPosition(currentRow).Y >= currentRow.ActualHeight / 2) dataSource.Insert(Math.Min(rowIndex + 1, dataSource.Count), draggingRow); else dataSource.Insert(rowIndex, draggingRow); } } else if (args.DropTargetType == DropTargetType.InsertRowsIntoGroup || dataView.Grid.IsGrouped) { var value = dataView.Grid.GetCellValue(rowData.RowHandle.Value, dataView.Grid.SortInfo[0].FieldName); TypeDescriptor.GetProperties(draggingRow.GetType())[dataView.Grid.SortInfo[0].FieldName].SetValue(draggingRow, value); if (args.DropTargetType == DropTargetType.InsertRowsAfter) { dataSource.Insert(Math.Min(rowIndex + 1, dataSource.Count), draggingRow); } else dataSource.Insert(rowIndex, draggingRow); dataView.Grid.RefreshData(); } } static MethodInfo IsSameGroupInfo = typeof(GridDragDropManager).GetMethod("IsSameGroup", BindingFlags.NonPublic | BindingFlags.Instance); protected bool IsSameGroup(DragDropManagerBase sourceManager, GroupInfo[] groupInfos, DependencyObject hitElement) { return (bool)IsSameGroupInfo.Invoke(this, new object[] { sourceManager, groupInfos, hitElement }); } static MethodInfo GetGroupInfosInfo = typeof(GridDragDropManager).GetMethod("GetGroupInfos", BindingFlags.NonPublic | BindingFlags.Instance); protected GroupInfo[] GetGroupInfos(int rowHandle) { return (GroupInfo[])GetGroupInfosInfo.Invoke(this, new object[] { rowHandle }); } static MethodInfo SetReorderDropInfoInfo = typeof(GridDragDropManager).GetMethod("SetReorderDropInfo", BindingFlags.NonPublic | BindingFlags.Instance); protected void SetReorderDropInfo(DragDropManagerBase sourceManager, int insertRowHandle, DependencyObject hitElement) { SetReorderDropInfoInfo.Invoke(this, new object[] { sourceManager, insertRowHandle, hitElement }); } static MethodInfo SetMoveToGroupRowDropInfoInfo = typeof(GridDragDropManager).GetMethod("SetMoveToGroupRowDropInfo", BindingFlags.NonPublic | BindingFlags.Instance); protected void SetMoveToGroupRowDropInfo(DragDropManagerBase sourceManager, int insertRowHandle, DependencyObject hitElement) { SetReorderDropInfoInfo.Invoke(this, new object[] { sourceManager, insertRowHandle, hitElement }); } protected bool IsGrouped(GridControl grid) { return grid.GroupCount > 0; } protected bool IsSorted(GridControl grid) { return grid.SortInfo.Count > 0; } protected bool IsSortedButNotGrouped(GridControl grid) { return IsSorted(grid) && !IsGrouped(grid); } protected bool ShouldReorderGroup(GridControl grid) { return grid.SortInfo.Count <= grid.GroupCount; } protected override void PerformDropToViewCore(DragDropManagerBase sourceManager) { GridViewHitInfoBase hitInfo = GetHitInfo(HitElement); if (BanDrop(hitInfo.RowHandle, hitInfo, sourceManager, DropTargetType.None)) { ClearDragInfo(sourceManager); return; } PerformDropToView(sourceManager, hitInfo as TableViewHitInfo, LastPosition, SetReorderDropInfo, (_) => SetMoveToGroupRowDropInfo, SetAddRowsDropInfo); } protected GridControl GetSourceGrid() { var parentRow = (FrameworkElement)LayoutHelper.FindParentObject<RowControl>(HitElement) ?? (FrameworkElement)LayoutHelper.FindParentObject<GridRowContent>(HitElement); return parentRow != null ? ((RowData)parentRow.DataContext).View.DataControl as GridControl : this.GridControl; } protected void PerformDropToView(DragDropManagerBase sourceManager, TableViewHitInfo hitInfo, Point pt, MoveRowsDelegate reorderDelegate, Func<bool, MoveRowsDelegate> groupDelegateExtractor, MoveRowsDelegate addRowsDelegate) { int insertRowHandle = hitInfo.RowHandle; var grid = GetSourceGrid(); if (this.GridControl.IsGroupRowHandle(insertRowHandle)) { groupDelegateExtractor(true)(sourceManager, insertRowHandle, HitElement); return; } if (IsSortedButNotGrouped(grid) || hitInfo.HitTest == TableViewHitTest.DataArea) { if (sourceManager.DraggingRows.Count > 0 && GetDataAreaElement(HitElement) != null/* && !ReferenceEquals(sourceManager, this)*/) addRowsDelegate(sourceManager, insertRowHandle, HitElement); else ClearDragInfo(sourceManager); return; } if (insertRowHandle == GridControl.InvalidRowHandle || insertRowHandle == GridControl.AutoFilterRowHandle || insertRowHandle == GridControl.NewItemRowHandle) { ClearDragInfo(sourceManager); return; } if (this.GridControl.GroupCount > 0) { int groupRowHandle = this.GridControl.GetParentRowHandle(insertRowHandle); if (ShouldReorderGroup(grid)) { if (!IsSameGroup(sourceManager, GetGroupInfos(groupRowHandle), HitElement)) groupDelegateExtractor(false)(sourceManager, groupRowHandle, HitElement); reorderDelegate(sourceManager, insertRowHandle, HitElement); } else groupDelegateExtractor(true)(sourceManager, groupRowHandle, HitElement); } else { reorderDelegate(sourceManager, insertRowHandle, HitElement); } } public delegate void MoveRowsDelegate(DragDropManagerBase sourceManager, int targetRowHandle, DependencyObject hitElement); } } Close Log
本站文章除注明转载外,均为本站原创或翻译
欢迎任何形式的转载,但请务必注明出处,尊重他人劳动成果
转载请注明:文章转载自:DevExpress控件中文网 [http://www.devexpresscn.com/]
本文地址:http://www.devexpresscn.com/Resources/CodeExamples-516.html
欢迎任何形式的转载,但请务必注明出处,尊重他人劳动成果
转载请注明:文章转载自:DevExpress控件中文网 [http://www.devexpresscn.com/]
本文地址:http://www.devexpresscn.com/Resources/CodeExamples-516.html
关键字: DevExpress WPF
评论列表
暂无评论
请谈谈你的看法 请使用IE或者Firefox浏览器,暂不支持Chrome!
慧都控件网为DevExpress界面控件的中国地区唯一正式授权经销商,正版控件销售公司,授权代理商,经销商及合作伙伴。
电话:400-700-1020
023-66090381
邮箱:sales@evget.com
相关资源
- DevExpress v15.2有哪些值得关注的新变化?
- 利用WizardControl构建多步向导界面
- DevExpress v15.2帮助文档下载大全
- ASP.NET MVC GridView强悍的数据处理 | 附在线演示
- DevExpress WPF 15.2代码示例:如何实现只选中一个项目
- DevExpress WPF 15.2代码示例:如何实现工具条合并
- 【视频专辑】DevExpress v15.2新功能介绍视频(25集全)
- DevExpress WPF 15.2代码示例:从集合中生成NavBarControl项目并自动分组
- DevExpress WPF 15.2代码示例:从集合中生成NavBarControl组和项目
- 【年终盘点】2015年DevExpress资源汇总(文档、视频、Demo、更新)
- ASP.NET MVC报表无与伦比的设计时体验 | 附在线演示