Reputation: 17
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;
}
Upvotes: 1
Views: 4025
Reputation: 16119
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;
}
}
Upvotes: 3
Reputation: 17
@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
Upvotes: 0