C#开发学习笔记:C#中实现两个GridControl之间的数据拖拽以及同一个GridControl中的数据行上下移动

本文详细介绍了如何使用DevExpress的Grid控件实现数据行的拖拽操作,包括单个和多个数据行的拖拽、数据行在不同Grid控件间的移动及在同一Grid控件内的上下移动等操作。

1.两个控件之间的拖拽

(1).拖拽发起方控件使用MouseDown事件获取需要拖拽的数据行的索引

DevExpress.XtraGrid.Views.Grid.ViewInfo.GridHitInfo GridHitInfo_temp = null;
private void tRC01GridControl_MouseDown(object sender, MouseEventArgs e)
{
 //获取鼠标当前所在坐标点的信息(该点相对于控件的坐标系)
 DevExpress.XtraGrid.Views.Grid.ViewInfo.GridHitInfo GridHitInfo = this.gridView3.CalcHitInfo(new Point(e.X, e.Y));
 //获取鼠标当前所在坐标的对应的数据行索引
 int MouseRowHandle = GridHitInfo.RowHandle;
 //如果索引大于0同时鼠标点击的是左键
 if (MouseRowHandle >= 0 && e.Button == MouseButtons.Left)
 {
     GridHitInfo_temp = GridHitInfo;
 }
}

注:如果需要拖拽多行,则可以在此步获取鼠标选中范围时点击的起始数据行和结束数据行的索引

(2).拖拽发起方控件使用MouseMove事件获取需要拖拽的数据行

private void tRC01GridControl_MouseMove(object sender, MouseEventArgs e)
{
	if (GridHitInfo_temp == null) return;
      if (e.Button != MouseButtons.Left) return;
     //通过鼠标按下时获取的数据行索引获取数据
     DataRow data = gridView3.GetDataRow(GridHitInfo_temp.RowHandle);
     int[] rows = gridView3.GetSelectedRows();//获取当前选中的数据行的索引
     //定义一个泛型集合存储拖拽的数据
     List<DataRow> row = new List<DataRow>();
     for (int i = 0; i < rows.Length; i++)
         row.Add(gridView3.GetDataRow((int)rows[i]));


     //拖拽发起方控件开始执行拖拽操作,拖拽操作的类型为Copy(复制)
     tRC01GridControl.DoDragDrop(row, DragDropEffects.Copy);
}
注:如果是拖拽多行,则使用SelectRange(int startRowHandle,int endRowHandle);其中两个参数则使用第一步获取到的起始与结束行索引


(3).设置目的控件的拖拽操作方式

private void tRC02GridControl_DragEnter(object sender, DragEventArgs e)
{
     //根据拖拽事件发起方所允许的拖放操作设置目的方的拖拽操作类型
      if (e.AllowedEffect==DragDropEffects.Move)
         e.Effect = DragDropEffects.Move;
      else
         e.Effect = DragDropEffects.Copy;
}


(4).拖拽完成,目的控件执行DragDrop事件

 private void tRC02GridControl_DragDrop(object sender, DragEventArgs e)
{
    GridControl grid = sender as GridControl;//将拖拽事件的触发对象(目的方)转为控件
    DataTable table = grid.DataSource as DataTable;//获取拖拽目的方的数据源

    //获取拖拽的源数据(在调用DoDragDrop()方法时传入)同时转换为传入的类型
    List<DataRow> row = e.Data.GetData(typeof(List<DataRow>)) as List<DataRow>;
    if (row != null && table != null)
    {
        if (row.Count > 0)
        {
            //判断当前拖拽操作的方式
            if (e.Effect != DragDropEffects.Move)
            {
                for (int i = 0; i < row.Count; i++)
                {
                    row[i]["Selection"] = "True";
                    table.ImportRow(row[i]);
                    row[i].Delete();  // 把原有的数据行删除(会在数据行的父表中删除)。
                }
            }
         }
    }
}


2.一个GridControl中的数据行上下移动

(1),(2),(3)步同上,只是调用对应的事件的控件为当前的控件

(4).执行DragDrop事件

 private void tRC02GridControl_DragDrop(object sender, DragEventArgs e)
{
    GridControl grid = sender as GridControl;//将拖拽事件的触发对象(目的方)转为控件
    //获取目的方控件的默认GridView
    DevExpress.XtraGrid.Views.Grid.GridView gridView = grid.DefaultView as DevExpress.XtraGrid.Views.Grid.GridView;
    DataTable table = grid.DataSource as DataTable;//获取拖拽目的方的数据源

    //根据鼠标在目的方的坐标获取对应的信息
    //该坐标是根据鼠标相对于的屏幕的位置(Control.MousePosition)使用控件的PointToClient()方法转换;
    //如果需要调试需要注意Control.MousePosition的坐标在调试状态下也会更改,因此调试时需要将断点设置在Control.MousePosition
    //转换为Point对象之后才能保证转换出来的鼠标相对于控件工作区域的坐标正确
    DevExpress.XtraGrid.Views.Grid.ViewInfo.GridHitInfo GridHitInfo = gridView.CalcHitInfo(grid.PointToClient(Control.MousePosition));

    //获取拖拽的源数据(在调用DoDragDrop()方法时传入)同时转换为传入的类型
    List<DataRow> row = e.Data.GetData(typeof(List<DataRow>)) as List<DataRow>;
    if (row != null && table != null)
    {
        if (row.Count > 0)
        {
            //判断当前拖拽操作的方式
            if (e.Effect == DragDropEffects.Move)
            {
                for (int i = 0; i < row.Count; i++)
                {
                    if (GridHitInfo.RowHandle >= 0)
                    {
                        /根据鼠标转换坐标之后计算出来其相对目的控件的坐标点所在行的索引新增一条空行
                        table.Rows.InsertAt(table.NewRow(), GridHitInfo.RowHandle);
                        //将拖拽的数据行的信息赋值到新增的空行中
                        table.Rows[GridHitInfo.RowHandle].ItemArray = row[i].ItemArray;

                    }
                    else
                    {
                        table.Rows.Add();
                        table.Rows[table.Rows.Count-1].ItemArray = row[i].ItemArray;
                    }

                    row[i].Delete();//删除原来的数据行(该行所在父表中删除)
                    table.AcceptChanges();//提交表所有的更改
                }
            }
        }
    }
}

注:使用Control.MousePosition获取鼠标标相对于屏幕的坐标时,在调试状态下Control.MousePosition也会随着鼠标的移动而改变,因此调试时

     为了使鼠标的屏幕坐标使用控件的PointToClient()方法转换为其相对于控件的坐标时正确,需要注意断点要打在转换之后


<think>嗯,用户问的是在DevExpress中如何实现两个GridControl之间拖拽效果,以及同一个GridControl内的拖拽。我得先回忆一下DevExpress的控件功能。 首先,DevExpress的GridControl本身有没有内置的拖拽支持呢?记得好像需要自己处理事件,比如DragDrop和DragOver。可能需要用到AllowDrop属性,还有处理鼠标事件来启动拖放操作。 对于同一个GridControl内部的拖拽,可能需要处理MouseDown、MouseMove和MouseUp事件来捕获拖动动作。获取当前数据,然后调整数据源的顺序,再重新绑定或者刷新GridControl。另外,可能需要使用DoDragDrop方法来启动拖拽操作,同时在目标位置处理DragOver和DragDrop事件,验证并执数据移动。 如果是两个不同的GridControl之间拖拽,步骤类似,但需要注意数据源的转换。比如,从一个GridControl拖到另一个,需要获取源数据,然后添加到目标的数据源中,可能需要移除源数据或者复制,取决于需求。这时候在DragDrop事件里要区分源和目标控件,处理数据的转移。 还需要考虑数据的格式,在拖拽时传递的数据类型,可能需要使用DataFormats来定义,或者直接传递数据对象。另外,确保目标控件的AllowDrop设置为true,这样才能接收拖放的数据。 记得在拖拽过程中处理异常,比如用户拖到不允许的位置,或者数据不兼容的情况,这时候要在DragOver事件中设置Effect为None,或者显示提示。 可能还需要用到HitInfo来确定鼠标所在的位置,这样在放置的时候知道插入的位置。比如,使用GridView的CalcHitInfo方法,根据鼠标坐标获取信息。 有没有相关的示例代码或者文档可以参考?可能需要查看DevExpress的官方文档,或者社区中的例子。比如,处理GridView的MouseDown事件,启动拖拽,然后在目标控件的DragOver中允许操作,最后在DragDrop中处理数据移动。 总结一下步骤: 1. 允许控件拖放:设置AllowDrop为true。 2. 处理源控件的Mouse事件,启动拖拽。 3. 在目标控件的DragOver事件中,验证数据并允许拖放。 4. 在DragDrop事件中,获取拖拽数据,更新数据源,刷新GridControl。 需要注意数据源的绑定方式,如果是绑定到DataTable或BindingList,可能需要使用可观察的集合来自动更新界面。或者在修改数据源后调用RefreshData方法。 对于同一个GridControl内的拖拽,可能需要重新排序数据源,比如移动某一的位置。如果是两个GridControl之间,可能需要从源数据源移除,添加到目标数据源。 另外,可能需要处理选中的索引,确保拖拽的是正确的数据。在事件中获取FocusedRowHandle或者SelectedRows,然后获取对应的数据对象。 可能还要考虑视觉效果,比如拖拽时的图标变化,或者高亮提示。这部分可能需要自定义绘制或者使用DevExpress提供的样式设置。 总之,核心步骤是处理拖放事件,获取数据,更新数据源,然后刷新控件显示。需要根据具体需求调整数据处理的逻辑,比如复制还是移动,以及如何处理数据源的变更通知。</think>在 DevExpress 中实现 GridControl 拖拽效果(跨控件或同控件)可通过以下步骤实现: --- ### **一、同一 GridControl拖拽** ```csharp // 启用拖放功能 gridView1.AllowDrop = true; // 1. 鼠标按下事件(开始拖拽) private void gridView1_MouseDown(object sender, MouseEventArgs e) { GridHitInfo hitInfo = gridView1.CalcHitInfo(e.Location); if (hitInfo.InRowCell) { // 获取当前数据 object rowData = gridView1.GetRow(hitInfo.RowHandle); // 启动拖拽 DoDragDrop(rowData, DragDropEffects.Move); } } // 2. 拖拽悬停时验证 private void gridView1_DragOver(object sender, DragEventArgs e) { e.Effect = DragDropEffects.Move; } // 3. 放置时调整顺序 private void gridView1_DragDrop(object sender, DragEventArgs e) { GridHitInfo hitInfo = gridView1.CalcHitInfo(gridView1.GridControl.PointToClient(new Point(e.X, e.Y))); if (hitInfo.RowHandle >= 0) { // 获取源数据和目标位置 object draggedData = e.Data.GetData(typeof(YourDataType)); int targetIndex = hitInfo.RowHandle; // 操作数据源(示例为 BindingList<T>) var dataSource = (BindingList<YourDataType>)gridControl1.DataSource; dataSource.Remove((YourDataType)draggedData); dataSource.Insert(targetIndex, (YourDataType)draggedData); // 刷新视图 gridView1.RefreshData(); } } ``` --- ### **二、跨 GridControl 拖拽** ```csharp // 设置两个 GridControl 允许拖放 gridControl1.AllowDrop = true; gridControl2.AllowDrop = true; // 1. 源 GridControl 拖出逻辑 private void gridView1_MouseMove(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { GridHitInfo hitInfo = gridView1.CalcHitInfo(e.Location); if (hitInfo.InRow) { object rowData = gridView1.GetRow(hitInfo.RowHandle); DoDragDrop(rowData, DragDropEffects.Copy); // 根据需求选 Move/Copy } } } // 2. 目标 GridControl 接收逻辑 private void gridControl2_DragDrop(object sender, DragEventArgs e) { GridHitInfo hitInfo = gridView2.CalcHitInfo(gridControl2.PointToClient(new Point(e.X, e.Y))); YourDataType draggedData = (YourDataType)e.Data.GetData(typeof(YourDataType)); // 操作目标数据源 var targetDataSource = (BindingList<YourDataType>)gridControl2.DataSource; targetDataSource.Add(draggedData); // 添加数据 // 若需移除源数据 var sourceDataSource = (BindingList<YourDataType>)gridControl1.DataSource; sourceDataSource.Remove(draggedData); gridView2.RefreshData(); gridView1.RefreshData(); } // 3. 拖拽悬停时验证格式 private void gridControl2_DragOver(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(typeof(YourDataType))) { e.Effect = DragDropEffects.Copy; } } ``` --- ### **三、关键配置** 1. **数据源类型**:需使用可更新集合(如 `BindingList<T>`),确保 UI 自动刷新。 2. **数据获取**:通过 `GetRow` 方法获取拖拽数据对象。 3. **效果控制**: - `DragDropEffects.Move`:移动数据(默认剪贴板为)。 - `DragDropEffects.Copy`:复制数据。 4. **HitInfo 验证**:通过 `CalcHitInfo` 确保拖放位置有效性。 --- ### **四、扩展优化** - **可视化提示**:在 `DragOver` 事件中高亮目标。 - **异步处理**:大数据量时使用 `BeginInvoke` 避免 UI 卡顿。 - **数据验证**:在 `DragDrop` 前检查数据是否符合目标要求。 通过以上代码,可灵活实现 DevExpress GridControl拖拽交互。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值