原文地址:https://wpf.2000things.com/2012/12/17/713-setting-the-cursor-to-an-image-of-an-uielement-while-dragging/
在拖拽操作的过程中,你可以通过GiveFeedback 事件的处理函数来修改鼠标光标的样子。甚至可以将拖拽控件生成图片作为鼠标光标。
下面是根据Brandon Cannaday的代码 http://www.switchonthecode.com/tutorials/wpf-tutorial-how-to-use-custom-cursors 写的一个例子。他的代码有给鼠标帮助类,
public class CursorHelper
{
private static class NativeMethods
{
public struct IconInfo
{
public bool fIcon;
public int xHotspot;
public int yHotspot;
public IntPtr hbmMask;
public IntPtr hbmColor;
}
[DllImport("user32.dll")]
public static extern SafeIconHandle CreateIconIndirect(ref IconInfo icon);
[DllImport("user32.dll")]
public static extern bool DestroyIcon(IntPtr hIcon);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetIconInfo(IntPtr hIcon, ref IconInfo pIconInfo);
}
[SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
private class SafeIconHandle : SafeHandleZeroOrMinusOneIsInvalid
{
public SafeIconHandle()
: base(true)
{
}
override protected bool ReleaseHandle()
{
return NativeMethods.DestroyIcon(handle);
}
}
private static Cursor InternalCreateCursor(System.Drawing.Bitmap bmp)
{
var iconInfo = new NativeMethods.IconInfo();
NativeMethods.GetIconInfo(bmp.GetHicon(), ref iconInfo);
iconInfo.xHotspot = 0;
iconInfo.yHotspot = 0;
iconInfo.fIcon = false;
SafeIconHandle cursorHandle = NativeMethods.CreateIconIndirect(ref iconInfo);
return CursorInteropHelper.Create(cursorHandle);
}
public static Cursor CreateCursor(UIElement element)
{
element.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
element.Arrange(new Rect(new Point(), element.DesiredSize));
RenderTargetBitmap rtb =
new RenderTargetBitmap(
(int)element.DesiredSize.Width,
(int)element.DesiredSize.Height,
96, 96, PixelFormats.Pbgra32);
rtb.Render(element);
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(rtb));
using (var ms = new MemoryStream())
{
encoder.Save(ms);
using (var bmp = new System.Drawing.Bitmap(ms))
{
return InternalCreateCursor(bmp);
}
}
}
}
然后我们做一个简单的界面,将一个Label拖入另一个Label中,并且将Label作为鼠标。
<StackPanel Orientation="Vertical" HorizontalAlignment="Center" Margin="45">
<Label Content="Data to drag" Background="AliceBlue" Padding="15,10"
MouseLeftButtonDown="Label_MouseLeftButtonDown"
GiveFeedback="Label_GiveFeedback"/>
<Label Content="Drag to here" Background="MediumSpringGreen" Padding="15,10" Margin="20"
AllowDrop="True" Drop="Label_Drop"/>
</StackPanel>
下面是拖拽操作的代码,在
GiveFeedback 事件处理函数中判断是否是Copy操作,如果是则改变鼠标。
private void Label_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
DataObject data = new DataObject(DataFormats.Text, ((Label)e.Source).Content);
DragDrop.DoDragDrop((DependencyObject)e.Source, data, DragDropEffects.Copy);
}
private void Label_Drop(object sender, DragEventArgs e)
{
((Label)e.Source).Content = (string)e.Data.GetData(DataFormats.Text);
}
private Cursor customCursor = null;
private void Label_GiveFeedback(object sender, GiveFeedbackEventArgs e)
{
if (e.Effects == DragDropEffects.Copy)
{
if (customCursor == null)
customCursor = CursorHelper.CreateCursor(e.Source as UIElement);
if (customCursor != null)
{
e.UseDefaultCursors = false;
Mouse.SetCursor(customCursor);
}
}
else
e.UseDefaultCursors = true;
e.Handled = true;
}