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#程序设计有所帮助。

以上是 C#实现Dev Grid拖拽移动行的方法 的全部内容, 来源链接: utcz.com/z/337695.html

回到顶部