gpt4 book ai didi

C# 拖放 : Show the dragged item while dragging

转载 作者:IT王子 更新时间:2023-10-29 04:38:51 28 4
gpt4 key购买 nike

我正在使用 Windows 窗体在 C# 中构建桌面应用程序。我有一个自定义控件,我希望能够将它拖放到我的应用程序中(而不是外部)。现在我正在使用通常的 DoDragDrop/OnDragOver/OnDragDrop 方法来实现它。有什么方法可以在控件被拖来拖去时连续绘制控件——有点像您在 JQuery 的拖放中看到的那样?我希望实际控件留在原地,但我想在用户拖动它时绘制其外观的副本。理想情况下,该副本甚至应该是半透明的,但这更像是“拥有它就好了”。

我能想到的唯一方法是将绘制代码放在主窗体的 OnPaint 方法中,但这似乎是一个不够优雅的解决方案。还有其他想法吗?如果控件将自己描绘成位图,事情会更容易吗?

最佳答案

我想我应该回来自己回答这个问题,因为我最终确实让它工作了。

我用这些函数创建了一个 CursorUtil 类:

public struct IconInfo {
public bool fIcon;
public int xHotspot;
public int yHotspot;
public IntPtr hbmMask;
public IntPtr hbmColor;
}

public class CursorUtil {
[DllImport("user32.dll")]
public static extern IntPtr CreateIconIndirect(ref IconInfo icon);

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetIconInfo(IntPtr hIcon, ref IconInfo pIconInfo);

[DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr handle);

[DllImport("user32.dll", CharSet = CharSet.Auto)]
extern static bool DestroyIcon(IntPtr handle);

// Based on the article and comments here:
// http://www.switchonthecode.com/tutorials/csharp-tutorial-how-to-use-custom-cursors
// Note that the returned Cursor must be disposed of after use, or you'll leak memory!
public static Cursor CreateCursor(Bitmap bm, int xHotspot, int yHotspot) {
IntPtr cursorPtr;
IntPtr ptr = bm.GetHicon();
IconInfo tmp = new IconInfo();
GetIconInfo(ptr, ref tmp);
tmp.xHotspot = xHotspot;
tmp.yHotspot = yHotspot;
tmp.fIcon = false;
cursorPtr = CreateIconIndirect(ref tmp);

if (tmp.hbmColor != IntPtr.Zero) DeleteObject(tmp.hbmColor);
if (tmp.hbmMask != IntPtr.Zero) DeleteObject(tmp.hbmMask);
if (ptr != IntPtr.Zero) DestroyIcon(ptr);

return new Cursor(cursorPtr);
}

public static Bitmap AsBitmap(Control c) {
Bitmap bm = new Bitmap(c.Width, c.Height);
c.DrawToBitmap(bm, new Rectangle(0, 0, c.Width, c.Height));
return bm;
}

然后我写了一个 Drag 类(也不是面向对象的,唉,但我认为在桌面应用程序中一次只能拖动一个东西)。这是该代码的一部分:

    public static void StartDragging(Control c) {
Dragged = c;
DisposeOldCursors();
Bitmap bm = CursorUtil.AsBitmap(c);
DragCursorMove = CursorUtil.CreateCursor((Bitmap)bm.Clone(), DragStart.X, DragStart.Y);
DragCursorLink = CursorUtil.CreateCursor((Bitmap)bm.Clone(), DragStart.X, DragStart.Y);
DragCursorCopy = CursorUtil.CreateCursor(CursorUtil.AddCopySymbol(bm), DragStart.X, DragStart.Y);
DragCursorNo = CursorUtil.CreateCursor(CursorUtil.AddNoSymbol(bm), DragStart.X, DragStart.Y);
//Debug.WriteLine("Starting drag");
}

// This gets called once when we move over a new control,
// or continuously if that control supports dropping.
public static void UpdateCursor(object sender, GiveFeedbackEventArgs fea) {
//Debug.WriteLine(MainForm.MousePosition);
fea.UseDefaultCursors = false;
//Debug.WriteLine("effect = " + fea.Effect);
if (fea.Effect == DragDropEffects.Move) {
Cursor.Current = DragCursorMove;

} else if (fea.Effect == DragDropEffects.Copy) {
Cursor.Current = DragCursorCopy;

} else if (fea.Effect == DragDropEffects.None) {
Cursor.Current = DragCursorNo;

} else if (fea.Effect == DragDropEffects.Link) {
Cursor.Current = DragCursorLink;

} else {
Cursor.Current = DragCursorMove;
}
}

您可以在设置控件时使用这些方法,例如在构造函数中:

GiveFeedback += new GiveFeedbackEventHandler(Drag.UpdateCursor);

在这个方法中:

    protected override void OnMouseMove(MouseEventArgs mea) {
if (Drag.IsDragging(mea)) {
Drag.StartDragging(this);
DragDropEffects dde = DoDragDrop(Plan, DragDropEffects.Move | DragDropEffects.Copy);
Drag.StopDragging();
}
}

关于C# 拖放 : Show the dragged item while dragging,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3240603/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com