欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C#实现Dev Grid拖拽移动行的方法

程序员文章站 2022-04-11 07:53:44
本文实例讲述了c#实现dev grid拖拽移动行的方法。分享给大家供大家参考。具体如下: 完整实例代码点击此处本站下载。     拖拽...

本文实例讲述了c#实现dev grid拖拽移动行的方法。分享给大家供大家参考。具体如下:

完整实例代码点击此处本站下载
   
拖拽时带行截图效果

C#实现Dev Grid拖拽移动行的方法

实现代码如下:

/// <summary>
/// 拖拽帮助类
/// </summary>
public static class draghelper
{
  /// <summary>
  /// bandedgridview 拖拽
  /// </summary>
  /// <param name="gvmain"></param>
  public static void draggridrow<t>(this bandedgridview gvmain)
  {
   // 拖拽遮罩控件
   dragmaster dragmaster = new dragmaster();
   // 当前拖拽行绘画区域
   rectangle _dragrowrect = rectangle.empty;
   gridcontrol gcmain = gvmain.gridcontrol;
   gridhitinfo _downhitinfo = null;
   //表格属性 允许拖拽
   gcmain.allowdrop = true;
   gvmain.optionsdetail.enablemasterviewmode = false;
   #region 将对象拖至边界时发生 dragover
   gcmain.dragover += delegate(object sender, system.windows.forms.drageventargs e)
   {
    if (e.data.getdatapresent(typeof(t)))
     e.effect = dragdropeffects.move;
    else
     e.effect = dragdropeffects.none;
   };
   #endregion
   #region 拖拽完成时处理数据 dragdrop
   gcmain.dragdrop += delegate(object sender, system.windows.forms.drageventargs e)
   {
    // 拖过来的新数据
    t newrow = (t)e.data.getdata(typeof(t));
    // 原来在此坐标的数据
    // e的坐标是相对于屏幕的
    var clientpoint = gcmain.pointtoclient(new point(e.x, e.y));
    gridhitinfo hitinfo = gvmain.calchitinfo(new point(clientpoint.x, clientpoint.y));
    var oldrow = (t)gvmain.getrow(hitinfo.rowhandle);
    // 如果相等则不处理
    if (oldrow == null || newrow == null) return;
    // 且目标位置不是最后一行的话要将所有序号重排
    // 原来的行号
    var oldindex = _downhitinfo.rowhandle;
    // 新的行号
    var newindex = hitinfo.rowhandle;
    bindingsource bs = (bindingsource)(gcmain.datasource);
    if (bs == null)
     return;
    bs.removeat(oldindex);
    bs.insert(oldindex, oldrow);
    bs.removeat(newindex);
    bs.insert(newindex, newrow);
    bs.resetbindings(false);
   };
   #endregion
   #region 鼠标按下 mousedown
   gcmain.mousedown += delegate(object sender, mouseeventargs e)
   {
    _downhitinfo = null;
    gridhitinfo hitinfo = gvmain.calchitinfo(new point(e.x, e.y));
    if (control.modifierkeys != keys.none) return;
    if (e.button == mousebuttons.left && hitinfo.rowhandle >= 0)
    {
     // 禁用的grid不支持拖拽
     if (!gvmain.optionsbehavior.editable
      || gvmain.optionsbehavior.readonly)
      return;
     // 只有点击最前面才能拖拽
     if (hitinfo.inrowcell)
      return;
     // 缓存
     _downhitinfo = hitinfo;
    }
   };
   #endregion
   #region 鼠标移动 mousemove
   gcmain.mousemove += delegate(object sender, mouseeventargs e)
   {
    if (e.button == mousebuttons.left)
    {
     if (_downhitinfo != null)
     {
      size dragsize = systeminformation.dragsize;
      // 偏离区域
      rectangle dragrect = new rectangle(new point(_downhitinfo.hitpoint.x - dragsize.width / 2, _downhitinfo.hitpoint.y - dragsize.height / 2), dragsize);
      if (!dragrect.contains(new point(e.x, e.y)))
      {
       // 屏幕坐标
       var p = gcmain.pointtoscreen(e.location);
       // 刷新是必须要的
       gcmain.refresh();
       // 获取当前行截图
       var bmp = getdragrowimage(gcmain, _downhitinfo, _dragrowrect);
       point offsetpoint = new point(p.x + 1, p.y - dragmaster.dragsize.height / 2);
       // 开始显示拖拽遮罩
       dragmaster.startdrag(bmp, offsetpoint, dragdropeffects.move);
       // 获取要拖拽的数据
       object row = gvmain.getrow(_downhitinfo.rowhandle);
       // 开始拖拽
       gcmain.dodragdrop(row, dragdropeffects.move);
       // 取消事件
       devexpress.utils.dxmouseeventargs.getmouseargs(e).handled = true;
       // 清空缓存
       _downhitinfo = null;
      }
     }
    }
   };
   #endregion
   #region 在用鼠标拖动某项时发生,是否允许继续拖放 querycontinuedrag
   gcmain.querycontinuedrag += delegate(object sender, querycontinuedrageventargs e)
   {
    switch (e.action)
    {
     case dragaction.continue:
      // 移动遮罩
      point offsetpoint = new point(cursor.position.x + 1, cursor.position.y - dragmaster.dragsize.height / 2);
      dragmaster.dodrag(offsetpoint, dragdropeffects.move, false);
      break;
     default:
      // 清空
      _dragrowrect = rectangle.empty;
      // 停止拖动
      dragmaster.enddrag();
      break;
    }
   };
   #endregion
   #region 点击行头移动行
   gvmain.customdrawrowindicator += delegate(object sender, rowindicatorcustomdraweventargs e)
   {
    if (_dragrowrect == rectangle.empty && _downhitinfo != null && _downhitinfo.rowhandle == e.rowhandle)
    {
     _dragrowrect = e.bounds;
    }
   };
   #endregion
  }
  /// <summary>
  /// gridview 拖拽
  /// </summary>
  /// <param name="gvmain"></param>
  public static void draggridrow<t>(this gridview gvmain)
  {
   // 拖拽遮罩控件
   dragmaster dragmaster = new dragmaster();
   // 当前拖拽行绘画区域
   rectangle _dragrowrect = rectangle.empty;
   gridcontrol gcmain = gvmain.gridcontrol;
   gridhitinfo _downhitinfo = null;
   //表格属性 允许拖拽
   gcmain.allowdrop = true;
   gvmain.optionsdetail.enablemasterviewmode = false;
   #region 将对象拖至边界时发生 dragover
   gcmain.dragover += delegate(object sender, system.windows.forms.drageventargs e)
   {
    if (e.data.getdatapresent(typeof(t)))
     e.effect = dragdropeffects.move;
    else
     e.effect = dragdropeffects.none;
   };
   #endregion
   #region 拖拽完成时处理数据 dragdrop
   gcmain.dragdrop += delegate(object sender, system.windows.forms.drageventargs e)
   {
    // 拖过来的新数据
    t newrow = (t)e.data.getdata(typeof(t));
    // 原来在此坐标的数据
    // e的坐标是相对于屏幕的
    var clientpoint = gcmain.pointtoclient(new point(e.x, e.y));
    gridhitinfo hitinfo = gvmain.calchitinfo(new point(clientpoint.x, clientpoint.y));
    var oldrow = (t)gvmain.getrow(hitinfo.rowhandle);
    // 如果相等则不处理
    if (oldrow == null || newrow == null) return;
    // 且目标位置不是最后一行的话要将所有序号重排
    // 原来的行号
    var oldindex = _downhitinfo.rowhandle;
    // 新的行号
    var newindex = hitinfo.rowhandle;
      bindingsource bs = (bindingsource)(gcmain.datasource);
    if (bs == null)
     return;
      bs.removeat(oldindex);
    bs.insert(oldindex, oldrow);
    bs.removeat(newindex);
    bs.insert(newindex, newrow);
    bs.resetbindings(false);
   };
   #endregion
   #region 鼠标按下 mousedown
   gcmain.mousedown += delegate(object sender, mouseeventargs e)
   {
    _downhitinfo = null;
    gridhitinfo hitinfo = gvmain.calchitinfo(new point(e.x, e.y));
    if (control.modifierkeys != keys.none) return;
    if (e.button == mousebuttons.left && hitinfo.rowhandle >= 0)
    {
     // 禁用的grid不支持拖拽
     if (!gvmain.optionsbehavior.editable
      || gvmain.optionsbehavior.readonly)
      return;
     // 只有点击最前面才能拖拽
     if (hitinfo.inrowcell)
      return;
     // 缓存
     _downhitinfo = hitinfo;
    }
   };
   #endregion
   #region 鼠标移动 mousemove
   gcmain.mousemove += delegate(object sender, mouseeventargs e)
   {
    if (e.button == mousebuttons.left)
    {
     if (_downhitinfo != null)
     {
      size dragsize = systeminformation.dragsize;
      // 偏离区域
      rectangle dragrect = new rectangle(new point(_downhitinfo.hitpoint.x - dragsize.width / 2, _downhitinfo.hitpoint.y - dragsize.height / 2), dragsize);
        if (!dragrect.contains(new point(e.x, e.y)))
      {
       // 屏幕坐标
       var p = gcmain.pointtoscreen(e.location);
       // 刷新是必须要的
       gcmain.refresh();
       // 获取当前行截图
       var bmp = getdragrowimage(gcmain, _downhitinfo, _dragrowrect);
       point offsetpoint = new point(p.x + 1, p.y - dragmaster.dragsize.height / 2);
       // 开始显示拖拽遮罩
       dragmaster.startdrag(bmp, offsetpoint, dragdropeffects.move);
       // 获取要拖拽的数据
       object row = gvmain.getrow(_downhitinfo.rowhandle);
       // 开始拖拽
       gcmain.dodragdrop(row, dragdropeffects.move);
       // 取消事件
       devexpress.utils.dxmouseeventargs.getmouseargs(e).handled = true;
       // 清空缓存
       _downhitinfo = null;
      }
     }
    }
   };
   #endregion
   #region 在用鼠标拖动某项时发生,是否允许继续拖放 querycontinuedrag
   gcmain.querycontinuedrag += delegate(object sender, querycontinuedrageventargs e)
   {
    switch (e.action)
    {
     case dragaction.continue:
      // 移动遮罩
      point offsetpoint = new point(cursor.position.x + 1, cursor.position.y - dragmaster.dragsize.height / 2);
      dragmaster.dodrag(offsetpoint, dragdropeffects.move, false);
      break;
     default:
      // 清空
      _dragrowrect = rectangle.empty;
      // 停止拖动
      dragmaster.enddrag();
      break;
    }
   };
   #endregion
   #region 点击行头移动行
   gvmain.customdrawrowindicator += delegate(object sender, rowindicatorcustomdraweventargs e)
   {
    if (_dragrowrect == rectangle.empty && _downhitinfo != null && _downhitinfo.rowhandle == e.rowhandle)
    {
     _dragrowrect = e.bounds;
    }
   };
   #endregion
   }
  /// <summary>
  /// 获取拖拽截图
  /// </summary>
  /// <param name="hitinfo"></param>
  /// <param name="gcmain"></param>
  /// <param name="dragrowrect"></param>
  /// <returns></returns>
  private static bitmap getdragrowimage(gridcontrol gcmain, gridhitinfo hitinfo, rectangle dragrowrect)
  {
   // 截图
   var bmp = devimagecapturer.getcontrolbitmap(gcmain, null
   , dragrowrect.width + 1, dragrowrect.top
   , gcmain.width - dragrowrect.width - 4, dragrowrect.height - 1);
     using (graphics g = graphics.fromimage(bmp))
   {
    var p1 = new point(1, 1);
    var p2 = new point(bmp.width - 1, 1);
    var p3 = new point(1, bmp.height - 2);
    var p4 = new point(bmp.width - 1, bmp.height - 2);
    using (pen pen = new pen(gcmain.forecolor))
    {
     g.drawline(pen, p1, p2);
     g.drawline(pen, p1, p3);
     g.drawline(pen, p2, p4);
     g.drawline(pen, p3, p4);
    }
   }
   return bmp;
  }
}
/// <summary>
/// 拖拽窗口
/// </summary>
public partial class dragwindow : devexpress.utils.win.topformbase
{
  private bitmap dragbitmap;
  private bool dragging;
  private point hotspot;
  public static readonly point invisiblepoint = new point(-100000, -100000);
  public dragwindow()
  {
   hotspot = point.empty;
   dragging = false;
   setstyle(controlstyles.selectable, false);
   this.size = size.empty;
   this.showintaskbar = false;
   form prevactive = form.activeform;
   initializecomponent();
  }
  void activateform(object sender, eventargs e)
  {
   form form = sender as form;
   if (form == null || !form.ishandlecreated) return;
   form.activate();
  }
  public void maketopmost()
  {
   updatezorder();
  }
  private void initializecomponent()
  {
   this.startposition = formstartposition.manual;
   dragbitmap = null;
   this.enabled = false;
   this.minimumsize = size.empty;
   this.size = size.empty;
   this.location = invisiblepoint;
   this.visible = false;
   this.tabstop = false;
   //this.opacity = 0.7;// devexpress.utils.dragdrop.dragwindow.defaultopacity;
  }
  protected void internalmovebitmap(point p)
  {
   //p.offset(-hotspot.x, -hotspot.y);
   this.suspendlayout();
   this.location = p;
   this.resumelayout();
  }
  protected override void onresize(system.eventargs e)
  {
   base.onresize(e);
  }
  public bool showdrag(point p)
  {
   if (this.backgroundimage == null) return false;
   dragging = true;
   visible = true;
   refresh();
   internalmovebitmap(p);
   return true;
  }
  public bool movedrag(point p)
  {
   if (!dragging) return false;
   internalmovebitmap(p);
   return true;
  }
  public bool hidedrag()
  {
   if (!dragging) return false;
   visible = false;
   backgroundimage = null;
   dragging = false;
   this.suspendlayout();
   this.size = size.empty;
   this.location = invisiblepoint;
   this.resumelayout();
   return true;
  }
  public point hotspot { get { return hotspot; } set { hotspot = value; } }
  public bitmap dragbitmap
  {
   get { return dragbitmap; }
   set
   {
    this.backgroundimage = value;
    if (value == null)
    {
     hidedrag();
    }
    else
     hotspot = new point(value.size.width / 2, value.size.height / 2);
    dragbitmap = value;
    size = backgroundimage.size;
   }
  }
}
/// <summary>
/// 截图
/// </summary>
public class devimagecapturer
{
  [system.runtime.interopservices.dllimport("user32.dll")]
  internal static extern intptr getdc(intptr dc);
  [system.runtime.interopservices.dllimport("user32.dll")]
  internal static extern int releasedc(intptr hwnd, intptr hdc);
  [system.runtime.interopservices.dllimport("user32.dll")]
  internal static extern intptr getdesktopwindow();
  [system.runtime.interopservices.dllimport("gdi32.dll")]
  internal static extern bool bitblt(intptr hdcdest, int nxdest, int nydest, int nwidth, int nheight, intptr hdcsrc, int nxsrc, int nysrc, uint dwrop);
  [system.runtime.interopservices.dllimport("gdi32.dll")]
  internal static extern intptr createcompatibledc(intptr hdc);
  [system.runtime.interopservices.dllimport("gdi32.dll")]
  internal static extern intptr createcompatiblebitmap(intptr hdc, int nwidth, int nheight);
  [system.runtime.interopservices.dllimport("gdi32.dll")]
  internal static extern bool deleteobject(intptr hobject);
  [system.runtime.interopservices.dllimport("gdi32.dll")]
  internal static extern intptr selectobject(intptr hdc, intptr obj);
  [system.runtime.interopservices.dllimport("gdi32.dll")]
  internal static extern intptr createsolidbrush(int color);
  [system.runtime.interopservices.dllimport("gdi32.dll")]
  internal static extern intptr createpatternbrush(intptr hbitmap);
  /// <summary>
  /// 获取控件的截图
  /// </summary>
  /// <param name="control">控件</param>
  /// <param name="pattern">图片</param>
  /// <returns></returns>
  public static bitmap getcontrolbitmap(control control, bitmap pattern)
  {
   int width = control.width;
   int height = control.height;
   if (control is form)
   {
    width = control.clientrectangle.width;
    height = control.clientrectangle.height;
   }
   intptr hdc = getdc(control.handle);
   intptr compdc = createcompatibledc(hdc);
   intptr comphbmp = createcompatiblebitmap(hdc, width, height);
   intptr prev = selectobject(compdc, comphbmp);
   intptr brush = intptr.zero, prevbrush = intptr.zero;
   if (pattern != null)
   {
    brush = createpatternbrush(pattern.gethbitmap());
    prevbrush = selectobject(compdc, brush);
   }
   point pt = new point(0, 0);
   bitblt(compdc, 0, 0, width, height, hdc, pt.x, pt.y, 0x00c000ca);
   selectobject(compdc, prev);
   if (prevbrush != intptr.zero)
    selectobject(compdc, prevbrush);
   releasedc(control.handle, hdc);
   nativemethods.deletedc(compdc);
   bitmap bmp = bitmap.fromhbitmap(comphbmp);
   deleteobject(comphbmp);
   if (brush != intptr.zero)
    deleteobject(brush);
   return bmp;
  }
  /// <summary>
  /// 获取控件的截图
  /// </summary>
  /// <param name="control">控件</param>
  /// <param name="pattern">图片</param>
  /// <param name="offsetx">x</param>
  /// <param name="offsety">y</param>
  /// <param name="width">宽</param>
  /// <param name="height">高</param>
  /// <returns></returns>
  public static bitmap getcontrolbitmap(control control, bitmap pattern, int offsetx = 0, int offsety = 0, int width = 0, int height = 0)
  {
   width = width == 0 ? control.width : width;
   height = height == 0 ? control.height : height;
   if (control is form)
   {
    width = control.clientrectangle.width;
    height = control.clientrectangle.height;
   }
   intptr hdc = getdc(control.handle);
   intptr compdc = createcompatibledc(hdc);
   intptr comphbmp = createcompatiblebitmap(hdc, width, height);
   intptr prev = selectobject(compdc, comphbmp);
   intptr brush = intptr.zero, prevbrush = intptr.zero;
   if (pattern != null)
   {
    brush = createpatternbrush(pattern.gethbitmap());
    prevbrush = selectobject(compdc, brush);
   }
   point pt = new point(offsetx, offsety);
   bitblt(compdc, 0, 0, width, height, hdc, pt.x, pt.y, 0x00c000ca);
   selectobject(compdc, prev);
   if (prevbrush != intptr.zero)
    selectobject(compdc, prevbrush);
   releasedc(control.handle, hdc);
   nativemethods.deletedc(compdc);
   bitmap bmp = bitmap.fromhbitmap(comphbmp);
   deleteobject(comphbmp);
   if (brush != intptr.zero)
    deleteobject(brush);
   return bmp;
  }
}
 public class dragmaster
 {
  [threadstatic]
  static dragwindow dragwindow;
  bool draginprogress;
  dragdropeffects effects;
  dragdropeffects lasteffect;
  static cursor customizationcursor = null;
  double _opacity = 0.7;
    public double opacity
  {
   get { return _opacity; }
   set { _opacity = value; }
  }
  public dragmaster()
  {
   draginprogress = false;
   lasteffect = effects = dragdropeffects.none;
  }
    dragwindow dragwindow
  {
   get
   {
    if (dragwindow == null) dragwindow = new dragwindow() { opacity = this.opacity };
    return dragwindow;
   }
  }
  public dragdropeffects lasteffect
  {
   get { return lasteffect; }
  }
  public bool draginprogress
  {
   get { return draginprogress; }
  }
    /// <summary>
  /// 绘制大小
  /// </summary>
  public size dragsize
  {
   get
   {
    if (dragwindow.dragbitmap == null) return size.empty;
    return dragwindow.dragbitmap.size;
   }
  }
  /// <summary>
  /// 开始拖拽
  /// </summary>
  /// <param name="bmp"></param>
  /// <param name="startpoint"></param>
  /// <param name="effects"></param>
  public void startdrag(bitmap bmp, point startpoint, dragdropeffects effects)
  {
   stopdrag();
   draginprogress = true;
   this.effects = effects;
   lasteffect = effects;
   dragwindow.maketopmost();
   dragwindow.dragbitmap = bmp;
   dragwindow.showdrag(startpoint);
   setdragcursor(effects);
  }
  /// <summary>
  /// 停止拖拽
  /// </summary>
  protected void stopdrag()
  {
   draginprogress = false;
   lasteffect = effects = dragdropeffects.none;
   dragwindow.hidedrag();
  }
  /// <summary>
  /// 设置拖拽鼠标类型
  /// </summary>
  /// <param name="e"></param>
  public void setdragcursor(dragdropeffects e)
  {
   if (e == dragdropeffects.none)
    cursor.current = customizationcursor;
   else
    cursor.current = cursors.default;
  }
  /// <summary>
  /// 拖拽
  /// </summary>
  /// <param name="p"></param>
  /// <param name="e"></param>
  /// <param name="setcursor"></param>
  public void dodrag(point p, dragdropeffects e, bool setcursor)
  {
   if (!draginprogress) return;
   lasteffect = e;
   if (setcursor) setdragcursor(e);
   dragwindow.movedrag(p);
  }
  /// <summary>
  /// 取消拖拽
  /// </summary>
  public void canceldrag()
  {
   if (!draginprogress) return;
   stopdrag();
  }
  /// <summary>
  /// 结束拖拽
  /// </summary>
  public void enddrag()
  {
   if (!draginprogress) return;
   stopdrag();
  }
  /// <summary>
  /// 自定义cursor
  /// </summary>
  static cursor customizationcursor
  {
   get
   {
    if (customizationcursor == null) customizationcursor = resourceimagehelper.createcursorfromresources("devexpress.xtratreelist.images.customization.cur", typeof(dragmaster).assembly);
    return customizationcursor;
   }
  }
}

希望本文所述对大家的c#程序设计有所帮助。