首页 > 编程 > C# > 正文

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

2020-01-24 01:52:54
字体:
来源:转载
供稿:网友

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

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表