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报表无与伦比的设计时体验 | 附在线演示
 
 
    


