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




