Tengo una pequeña aplicación WPF que tiene una ventana con un control de imagen. El control de imagen muestra una imagen del sistema de archivos. Quiero que el usuario pueda arrastrar la imagen y soltarla en su escritorio o en cualquier lugar para guardarla. Funciona bien
Pero quiero mostrar una miniatura de imagen pequeña junto con el cursor del mouse cuando el usuario la arrastra. Al igual que arrastramos una imagen del explorador de archivos de Windows a otro lugar. ¿Cómo lograrlo?
Comportamiento actual de arrastrar / soltar
Comportamiento deseado
Aquí está mi código XAML
<Grid>
<Image x:Name="img" Height="100" Width="100" Margin="100,30,0,0"/>
</Grid>
Aquí está el código C #
public partial class MainWindow : Window
{
string imgPath;
Point start;
bool dragStart = false;
public MainWindow()
{
InitializeComponent();
imgPath = "C:\\Pictures\\flower.jpg";
ImageSource imageSource = new BitmapImage(new Uri(imgPath));
img.Source = imageSource;
window.PreviewMouseMove += Window_PreviewMouseMove;
window.PreviewMouseUp += Window_PreviewMouseUp;
window.Closing += Window_Closing;
img.PreviewMouseLeftButtonDown += Img_PreviewMouseLeftButtonDown;
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
window.PreviewMouseMove -= Window_PreviewMouseMove;
window.PreviewMouseUp -= Window_PreviewMouseUp;
window.Closing -= Window_Closing;
img.PreviewMouseLeftButtonDown -= Img_PreviewMouseLeftButtonDown;
}
private void Window_PreviewMouseMove(object sender, MouseEventArgs e)
{
if (!dragStart) return;
if (e.LeftButton != MouseButtonState.Pressed)
{
dragStart = false; return;
}
Point mpos = e.GetPosition(null);
Vector diff = this.start - mpos;
if (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance &&
Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance)
{
string[] file = { imgPath };
DataObject d = new DataObject();
d.SetData(DataFormats.Text, file[0]);
d.SetData(DataFormats.FileDrop, file);
DragDrop.DoDragDrop(this, d, DragDropEffects.Copy);
}
}
private void Img_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
this.start = e.GetPosition(null);
dragStart = true;
}
private void Window_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
dragStart = false;
}
}
c#
wpf
drag-and-drop
Riz
fuente
fuente
DragDrop.GiveFeedback
. Compruebe esto stackoverflow.com/questions/4878004/…Respuestas:
Oficialmente, se supone que debe utilizar la interfaz IDragSourceHelper para agregar un mapa de bits de vista previa a una operación de arrastrar y soltar.
Desafortunadamente, esta interfaz usa el método IDataObject :: SetData que no está implementado a nivel COM por la clase .NET DataObject, solo a nivel .NET.
La solución es reutilizar un IDataObject proporcionado por el Shell para cualquier elemento del Shell (aquí un archivo), utilizando la función SHCreateItemFromParsingName y el método IShellItem :: BindToHandler .
Tenga en cuenta que estas funciones agregan automáticamente formatos de portapapeles como FileDrop, pero aún tenemos que usar IDragSourceHelper para agregar la imagen de vista previa.
Así es como puedes usarlo:
Y aquí está el código:
fuente
Aquí, prueba esto. "Recoge" un cuadrado rojo transparente alrededor de la posición del mouse y lo "suelta" cuando hace clic nuevamente.
En realidad, desearía crear el hilo haciendo la interoperabilidad al hacer clic y detenerlo (no abortarlo) cuando lo suelte.
Y código detrás:
fuente