当前位置:主页 > 软件编程 > .NET代码 >

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

时间:2021-11-25 11:32:58 | 栏目:.NET代码 | 点击:

本文实例讲述了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#程序设计有所帮助。

您可能感兴趣的文章:

相关文章