简体   繁体   中英

How To Drag and Drop Images inside Canvas in WPF using C#

I am able to dynamically add images into the WPF Canvas control as child elements but failing to drag & drop those images inside the canvas. Please help me as how could i move or drag/drop images inside the canvas window.

Thanks in advance.

Below is what I have done so far:

<Canvas x:Name="canvasImages" Height="325" Margin="0,0,0,0" Width="430" 
HorizontalAlignment="Left" VerticalAlignment="Top" AllowDrop="True" 
PreviewMouseLeftButtonDown="MouseLeftButtonDown" 
PreviewMouseLeftButtonUp="MouseLeftButtonUp" 
PreviewMouseMove="MouseMove" 
MaxWidth="430" MaxHeight="325" 
ScrollViewer.HorizontalScrollBarVisibility="Visible"/>
</Grid>

**Code**
OpenFileDialog op = new OpenFileDialog();
op.Title = "Select Multiple Pictures";
op.Multiselect = true;
op.Filter = "Image files (*.jpg, *.jpeg, *.jpe, *.jfif, *.png) | 
*.jpg; *.jpeg; *.jpe; *.jfif; *.png";

foreach (string imageFile in op.FileNames)
{
 Image img = new Image();
 img.Source = new BitmapImage(new Uri(imageFile));
 img.Height = 100;
 img.Width = 100;
 img.AllowDrop = true;
 Canvas.SetTop(img, y); //Setting up images to the Top position
 Canvas.SetLeft(img, x); //Setting up images to the left position
 canvasImages.Children.Add(img);
}

private new void MouseLeftButtonDown(object sender, 
MouseButtonEventArgs 
e)
 {
  IsDragging = true;
  draggedItem = (UIElement)sender;
  itemRelativePosition = e.GetPosition(draggedItem);
}

private new void MouseMove(object sender, 
System.Windows.Input.MouseEventArgs e)
{
 if (!IsDragging)
     return;
 Point canvasRelativePosition = e.GetPosition(canvasImages);
 Canvas.SetTop(draggedItem, canvasRelativePosition.Y - 
 itemRelativePosition.Y);
 Canvas.SetLeft(draggedItem, canvasRelativePosition.X - 
 itemRelativePosition.X);
}

private new void MouseLeftButtonUp(object sender, MouseButtonEventArgs  
e)
{
   if (!IsDragging)
     return;
   IsDragging = false;
}

@Mark, Here are the XAML code and the respective Class for your perusal. Basically I am allowing multiple selection of images by "OpenFileDialog()" and adding those images dynamically to Canvas control as mentioned in my previous code, which then i am failing to drag around those images internally within the Canvas control.

Below is the XAML Code

<Window x:Class="PicturesMovement.CanvasControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Connectlite Clients" 
    Height="394" Width="445"
    WindowStartupLocation="CenterScreen" ResizeMode="NoResize">
   <Grid Margin="0,0,2,0" Background="{DynamicResource {x:Static                  
     SystemColors.MenuBarBrushKey}}">
    <Button x:Name="Select" Content="Select" HorizontalAlignment="Left" 
     Height="22"  Margin="329,328,0,0" VerticalAlignment="Top" Width="42"                       
     Click="SelectImages"/>
    <Button x:Name="Cancel" Content="Cancel" HorizontalAlignment="Left"                       
     Margin="374,328,0,0" VerticalAlignment="Top" Width="49" 
     Click="closeBox"/>
    <Canvas x:Name="canvasImages" Height="325" Margin="0,0,0,0" 
      Width="430" HorizontalAlignment="Left" VerticalAlignment="Top" 
       AllowDrop="True"  PreviewMouseDown="PreviewMouseDown" 
         PreviewMouseUp="PreviewMouseUp"                     
         PreviewMouseMove="PreviewMouseMove" MaxWidth="430" 
        MaxHeight="325"                    
        ScrollViewer.HorizontalScrollBarVisibility="Visible"/>
</Grid>
</Window>

Below are the respective Class that triggers those Mouse Events

public partial class CanvasControl : System.Windows.Window,          
         System.Windows.Markup.IComponentConnector {

   this.canvasImages.PreviewMouseDown += new                       
   System.Windows.Input.MouseButtonEventHandler 
    (this.PreviewMouseDown);

   this.canvasImages.PreviewMouseUp += new                   
    System.Windows.Input.MouseButtonEventHandler 
       (this.PreviewMouseUp);

   this.canvasImages.PreviewMouseMove += new 
    System.Windows.Input.MouseEventHandler        
        (this.PreviewMouseMove);
}

Any suggestions will be highly appreciated...Thanks

Ok, a few things wrong here...

1) Your mouse down handler has to be on the image, not the canvas, otherwise your code has no way of knowing which item is being dragged.

2) Once you've clicked on an image the handler should capture the mouse for the canvas so that you get all mouse move messages.

3) The Canvas MouseMove and MouseUp handlers then need to be handled accordingly.

4) The Canvas needs to have a background. If you don't give it a background then it's effectively transparent to the hit-testing and you won't get mouse messages for it. If you don't want it to have a visible background then set it to Transparent .

So your Canvas tag needs to look like this:

<Canvas x:Name="canvasImages" Height="325" Margin="0,0,0,0" Width="430" 
    HorizontalAlignment="Left" VerticalAlignment="Top" AllowDrop="True" 
    PreviewMouseLeftButtonUp="CanvasImages_PreviewMouseLeftButtonUp" 
    PreviewMouseMove="CanvasImages_PreviewMouseMove" 
    MaxWidth="430" MaxHeight="325" 
    ScrollViewer.HorizontalScrollBarVisibility="Visible"
    Background="Transparent" />

And every image you create needs to have a handler set for it's MouseDown event:

img.MouseLeftButtonDown += Img_MouseLeftButtonDown;

Then it's just a matter is implementing your handlers like this:

private void Img_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    this.draggedItem = (UIElement)sender;
    itemRelativePosition = e.GetPosition(this.draggedItem);
    e.Handled = true;
}

private void CanvasImages_PreviewMouseMove(object sender, MouseEventArgs e)
{
    if (this.draggedItem == null)
        return;
    var newPos = e.GetPosition(canvasImages) - itemRelativePosition;
    Canvas.SetTop(this.draggedItem, newPos.Y);
    Canvas.SetLeft(this.draggedItem, newPos.X);
    canvasImages.CaptureMouse();
    e.Handled = true;
}

private void CanvasImages_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    if (this.draggedItem != null)
    {
        this.draggedItem = null;
        canvasImages.ReleaseMouseCapture();
        e.Handled = true;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM