我在my WinForms project中使用DevExpress
控件。我需要通过使用BehaviorManager
拖放来重新排序组行(包括其详细信息)(除了重新排序详细信息中的行)。对于拖放行,我编写了以下代码:
private void Behavior_DragOver(object sender, DragOverEventArgs e)
{
DragOverGridEventArgs args = DragOverGridEventArgs.GetDragOverGridEventArgs(e);
e.InsertType = args.InsertType;
e.InsertIndicatorLocation = args.InsertIndicatorLocation;
e.Action = args.Action;
Cursor.Current = args.Cursor;
args.Handled = true;
}
private void Behavior_DragDrop(object sender, DragDropEventArgs e)
{
GridView targetGrid = e.Target as GridView;
GridView sourceGrid = e.Source as GridView;
if (e.Action == DragDropActions.None || targetGrid != sourceGrid)
return;
DataTable sourceTable = sourceGrid.GridControl.DataSource as DataTable;
Point hitPoint = targetGrid.GridControl.PointToClient(Cursor.Position);
GridHitInfo hitInfo = targetGrid.CalcHitInfo(hitPoint);
int[] sourceHandles = e.GetData<int[]>();
int targetRowHandle = hitInfo.RowHandle;
int targetRowIndex = targetGrid.GetDataSourceRowIndex(targetRowHandle);
List<DataRow> draggedRows = new List<DataRow>();
foreach (int sourceHandle in sourceHandles) {
int oldRowIndex = sourceGrid.GetDataSourceRowIndex(sourceHandle);
DataRow oldRow = sourceTable.Rows[oldRowIndex];
draggedRows.Add(oldRow);
}
int newRowIndex;
switch (e.InsertType) {
case InsertType.Before:
newRowIndex = targetRowIndex > sourceHandles[sourceHandles.Length - 1]
? targetRowIndex - 1 : targetRowIndex;
for (int i = draggedRows.Count - 1; i >= 0; i--) {
DataRow oldRow = draggedRows[i];
DataRow newRow = sourceTable.NewRow();
newRow.ItemArray = oldRow.ItemArray;
sourceTable.Rows.Remove(oldRow);
sourceTable.Rows.InsertAt(newRow, newRowIndex);
}
break;
case InsertType.After:
newRowIndex = targetRowIndex < sourceHandles[0]
? targetRowIndex + 1 : targetRowIndex;
for (int i = 0; i < draggedRows.Count; i++) {
DataRow oldRow = draggedRows[i];
DataRow newRow = sourceTable.NewRow();
newRow.ItemArray = oldRow.ItemArray;
sourceTable.Rows.Remove(oldRow);
sourceTable.Rows.InsertAt(newRow, newRowIndex);
}
break;
default:
newRowIndex = -1;
break;
}
int insertedIndex = targetGrid.GetRowHandle(newRowIndex);
targetGrid.FocusedRowHandle = insertedIndex;
targetGrid.SelectRow(targetGrid.FocusedRowHandle);
}
例如,我想通过拖放替换Level3和Level6组行的位置。
我该怎么做?
3条答案
按热度按时间fnatzsnv1#
这个答案使用了一个自定义的
GridViewEx
类,它继承自GridView
,允许以一种干净的方式实现使用拖放重新排序分组行的目标,而不会在主窗体中混入大量代码。您的帖子和附加评论陈述了两个要求,我还添加了第三个目标,使外观和感觉与记录中已经存在的拖放功能相似。此自定义版本只需在Designer.cs文件中手动换出即可。
在该示例中,反馈线对于“目标行之前”为蓝色,并且对于“目标行之后”为红色。
在操作之前展开的组将保持该状态。
GridViewEx-clone可以从GitHub获得演示项目。
GridViewEx
维护自己的GroupDragDropState
以避免与BehaviorManager
操作的潜在冲突。如果鼠标按下光标在任何方向移动超过10个位置,则进入
Drag
状态。拖拽反馈
进入拖动状态会对点击的行进行屏幕截图。* 为了确保 *
Graphics.CopyFromScreen
* 方法的正确操作,appconfig.cs已被修改为逐屏DPI感知 *。appconfig.cs
GridViewEx.cs
此图像被分配给
_dragFeedbackLabel
成员的BackgroundImage
,该成员是一个无边框窗体,可以在主窗体的矩形外部绘制。当可见时,此窗体通过MessageFilter
拦截WM_MOUSEMOVE
消息来跟踪鼠标光标的移动。行分隔符是通过处理
GridView.CustomDrawGroupRow
事件绘制的。当
DropBelow
值在目标行更改时在拖动 * 或 * 的中点处切换时,需要重新绘制受影响的行。OnDrop
删除记录的
ItemsArray
被隐藏在字典中,以便在新索引处插入相同的DataRow
示例之前进行重新分配。根据MouseMove
处理程序中设置的DropBelow
布尔值对插入操作进行调整。杂项
GridViewEx
采用了一种只启用自定义排序的总括方法,初步测试表明,当前形式的拖放对于关键字分组的工作原理与对于级别的工作原理相同。ecr0jaav2#
我尝试了一些修改,但是没有通过BehaviorManager成功应用,最后我使用了网格控件grid_DragDrop、grid_DragOver、view_MouseDown和view_MouseMove事件代替了行为管理器,另外我在SetUpGrid函数中添加了一些代码行。
ecfsfe2w3#
当一个列被分组时,它也同时被排序。因此,你必须阻止排序(至少对于
Level
列)。我这里有一个没有BehaviorManager
的旧版本DevExpress
。但是你也可以用这个旧版本实现这个行为。您可以使用
DragDrop
,DragOver
,MouseDown
和MouseMove
(类似于muludag answer)。拖放操作仅适用于分组列Level
(通过PinBack更新):由Masoud编辑:
通过以下更改,我们可以重新排序分组的行和行两者: