C# Drag and Drop Image within Canvas - c#

I tried to Google how to make drag & drop for UIElements on a Canvas, but couldn't find anything that I'm looking for.
I got a C# WPF application with a Window. Inside the Window I got a Canvas where I can add Images to.
What I want is to be able to Drag & Drop the Images, while staying within the Canvas' borders.
I also want this to be in code, so not in the xaml.
I got this in the function where I add/update the Images to the Canvas. The TODO's should be replaced for the Drag & Drop events.
Image img = ImageList[i].Image;
img.Name = "Image" + i;
// TODO: Drag and Drop event for Image
// TODO: Check if Left and Top are within Canvas (minus width / height of Image)
Canvas.SetLeft(img, Left); // Default Left when adding the image = 0
Canvas.SetTop(img, Top); // Default Top when adding the image = 0
MyCanvas.Children.Add(img);
OnPropertyChanged("MyCanvas");
PS: Though this is for later, if someone has code to drag and drop multiple images at once as an additional bonus, I would appreciate it.
Thanks in advance for the help.

Fixed my problem below, by using the following code:
img.AllowDrop = true;
img.PreviewMouseLeftButtonDown += this.MouseLeftButtonDown;
img.PreviewMouseMove += this.MouseMove;
img.PreviewMouseLeftButtonUp += this.PreviewMouseLeftButtonUp;
private object movingObject;
private double firstXPos, firstYPos;
private void MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
// In this event, we get the current mouse position on the control to use it in the MouseMove event.
Image img = sender as Image;
Canvas canvas = img.Parent as Canvas;
firstXPos = e.GetPosition(img).X;
firstYPos = e.GetPosition(img).Y;
movingObject = sender;
// Put the image currently being dragged on top of the others
int top = Canvas.GetZIndex(img);
foreach (Image child in canvas.Children)
if (top < Canvas.GetZIndex(child))
top = Canvas.GetZIndex(child);
Canvas.SetZIndex(img, top + 1);
}
private void PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) {
Image img = sender as Image;
Canvas canvas = img.Parent as Canvas;
movingObject = null;
// Put the image currently being dragged on top of the others
int top = Canvas.GetZIndex(img);
foreach (Image child in canvas.Children)
if (top > Canvas.GetZIndex(child))
top = Canvas.GetZIndex(child);
Canvas.SetZIndex(img, top + 1);
}
private void MouseMove(object sender, MouseEventArgs e) {
if (e.LeftButton == MouseButtonState.Pressed && sender == movingObject) {
Image img = sender as Image;
Canvas canvas = img.Parent as Canvas;
double newLeft = e.GetPosition(canvas).X - firstXPos - canvas.Margin.Left;
// newLeft inside canvas right-border?
if (newLeft > canvas.Margin.Left + canvas.ActualWidth - img.ActualWidth)
newLeft = canvas.Margin.Left + canvas.ActualWidth - img.ActualWidth;
// newLeft inside canvas left-border?
else if (newLeft < canvas.Margin.Left)
newLeft = canvas.Margin.Left;
img.SetValue(Canvas.LeftProperty, newLeft);
double newTop = e.GetPosition(canvas).Y - firstYPos - canvas.Margin.Top;
// newTop inside canvas bottom-border?
if (newTop > canvas.Margin.Top + canvas.ActualHeight - img.ActualHeight)
newTop = canvas.Margin.Top + canvas.ActualHeight - img.ActualHeight;
// newTop inside canvas top-border?
else if (newTop < canvas.Margin.Top)
newTop = canvas.Margin.Top;
img.SetValue(Canvas.TopProperty, newTop);
}
}
This code allows me to drag-and-drop the Images inside the Canvas, without leaving the Canvas itself.
Now I just need to be able to do two more things:
Fix a little bug where my Mouse slips of the Image when I drag them around to fast. This happens quite often, even when I'm not even moving the dragging image around THAT fast.. Fixed by using the solution mentioned in my other question.
Making it able to drag-and-drop multiple images at once, preferably by selecting multiple first, and then drag-and-drop the whole bunch of them while staying inside the Canvas.
Will make a new Question for this.

I was did a project that uses a chunk of your code and does drag and drop on canvas, look into it and see if there be any difference, dont really have the time to check
private void pinCanvas_PreviewMouseLeftButtonDown_1(object sender, MouseButtonEventArgs e)
{
// Point pt = e.GetPosition(pinCanvas);
// Curosor.Text = String.Format("You are at ({0}in, {1}in) in window coordinates", (pt.X / (96 / 72)) * 1/72, (pt.Y / (96 / 72)) * 1/72);
}
bool captured = false;
double x_shape, x_canvas, y_shape, y_canvas;
UIElement source = null;
string elementName;
double elementHeight, elementWidth;
private void pinCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
setCanvasSize();
source = (UIElement)sender;
elementName = ((Label)source).Name;
switch (elementName)
{
case "pinTextBox" :
elementHeight = pinActualHeight;
elementWidth = pinActualWidth;
break;
case "serialTextBox" :
elementHeight = serialActualHeight;
elementWidth = serialActualWidth;
break;
case "batchTextBox" :
elementHeight = batchActualHeight;
elementWidth = batchActualWidth;
break;
}
Mouse.Capture(source);
captured = true;
x_shape = Canvas.GetLeft(source);
x_canvas = e.GetPosition(Maincanvas).X;
y_shape = Canvas.GetTop(source);
y_canvas = e.GetPosition(Maincanvas).Y;
}
private void pinCanvas_MouseMove(object sender, MouseEventArgs e)
{
if (captured)
{
double x = e.GetPosition(Maincanvas).X;
double y = e.GetPosition(Maincanvas).Y;
var xCond = Math.Round(appActivities.DIP2Inch(x_shape), 4).ToString();
var yCond = Math.Round(appActivities.DIP2Inch(y_shape), 4).ToString();
var name = ((Label)source).Name;
x_shape += x - x_canvas;
// if ((x_shape < Maincanvas.ActualWidth - elementWidth) && x_shape > 0)
// {
Canvas.SetLeft(source, x_shape);
switch (name)
{
case "pinTextBox" :
pinOffsetLeft.Text = xCond;
break;
case "serialTextBox" :
serialOffsetLeft.Text = xCond;
break;
case "batchTextBox" :
batchOffsetLeft.Text = xCond;
break;
}
// }
x_canvas = x;
y_shape += y - y_canvas;
// if (y_shape < Maincanvas.ActualHeight - elementHeight && y_shape > 0)
// {
Canvas.SetTop(source, y_shape);
switch (name)
{
case "pinTextBox":
pinOffsetTop.Text = yCond;
break;
case "serialTextBox":
serialOffsetTop.Text = yCond;
break;
case "batchTextBox":
batchOffsetTop.Text = yCond;
break;
}
// }
y_canvas = y;
}
}
private void pinCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
Mouse.Capture(null);
captured = false;
// MessageBox.Show((Canvas.GetTop(source)).ToString());
/* if (Canvas.GetTop(source) < 0)
{
Canvas.SetTop(source, 0);
}
if (Canvas.GetLeft(source) < 0)
{
Canvas.SetLeft(source, 0);
}
if (Canvas.GetLeft(source) > Maincanvas.ActualWidth - elementWidth)
{
// MessageBox.Show("Left Too Much " + (Canvas.GetLeft(source) * 1/96).ToString());
Canvas.SetLeft(source, Maincanvas.ActualWidth - elementWidth);
}
if (Canvas.GetTop(source) > Maincanvas.ActualHeight - elementHeight)
{
Canvas.SetTop(source, Maincanvas.ActualHeight - elementHeight);
} */
oneElemntTorched = true;
//MessageBox.Show(this.pinTextBox.ActualHeight.ToString() + ", " + this.pinTextBox.ActualWidth.ToString());
}

Related

Dragging a User Control

I am trying to make a UserControl draggable and I'm stuck and I have no idea why.
Basing myself on the answer here: How to drag a UserControl inside a Canvas
This portion of code is where I'm stuck:
private void Control_MouseMove(object sender, MouseEventArgs e)
{
var userControl= sender as UserControl;
Point currentPosition = e.GetPosition(userControl);
var transform = userControl.RenderTransform as TranslateTransform;
if (transform == null)
{
transform = new TranslateTransform();
userControl.RenderTransform = transform;
}
transform.X = currentPosition.X - clickPosition.X;
transform.Y = currentPosition.Y - clickPosition.Y;
}
}
What happens is that while dragging, the control jumps back and forth from its new position to it's old position.
When I change the above code to:
Point currentPosition = e.GetPosition(null);
The dragging works without the jumping back to the original position, but it is obviously offset. The UserControl in question does not have a parent control (in the sense that this.Parent is null).
The solution might be obvious but I'm just not seeing it. Any ideas?
Use LayoutTransform. RenderTransform only makes the UIElement "looks like" it is at the new position. This means that the first time the event triggers (first move), it is working as intended, but thereafter, the position is still at the original position, but it's being render-transformed to look like it has moved - this makes your move event go crazy.
It's still better to wrap your control in a Canvas, in my opinion. Using LayoutTransform is usually not recommended.
Step1: Add the Properties in UserControl
Point _anchorPoint;
Point _currentPoint;
bool _isInDrag;
private readonly TranslateTransform _transform = new TranslateTransform();
Step 2: Initialize your Constructor with following EventHandlers
this.MouseLeftButtonDown += new MouseButtonEventHandler(Control_MouseLeftButtonDown);
this.MouseLeftButtonUp += new MouseButtonEventHandler(Control_MouseLeftButtonUp);
this.MouseMove += new MouseEventHandler(Control_MouseMove);
3.Implement the Event Methods
private void Control_MouseMove(object sender, MouseEventArgs e)
{
if (!_isInDrag) return;
_currentPoint = e.GetPosition(null);
//This is the change to the position that we want to apply
Point delta = new Point();
delta.X = _currentPoint.X - _anchorPoint.X;
delta.Y = _currentPoint.Y - _anchorPoint.Y;
//Calculate user control edges
var leftEdge = Margin.Left + _transform.X + delta.X;
var topEdge = Margin.Top + _transform.Y + delta.Y;
var rightEdge = Width + Margin.Left + _transform.X + delta.X;
var bottomEdge = Height + Margin.Top + _transform.Y + delta.Y;
//Set the delta to 0 if it goes over _parentGrid edges
if (leftEdge < 0) delta.X = 0;
if (topEdge < 0) delta.Y = 0;
//_ParentGridName is called from MDIParent.GridName
if (rightEdge > _ParentGridName.Width) delta.X = 0;
if (bottomEdge > _ParentGridName.Height) delta.Y = 0;
//Apply the delta to the user control
_transform.X += delta.X;
_transform.Y += delta.Y;
RenderTransform = _transform;
_anchorPoint = _currentPoint;
}
private void Control_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (_isInDrag)
{
var element = sender as FrameworkElement;
element.ReleaseMouseCapture();
_isInDrag = false;
e.Handled = true;
}
}
private void Control_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var element = sender as FrameworkElement;
_anchorPoint = e.GetPosition(null);
if (element != null) element.CaptureMouse();
_isInDrag = true;
e.Handled = true;
}

Drag User Control, but keep it inside the bounds of its parent in WPF

I have a user control that I am dragging inside of a grid. The Z-Index is set pretty high so that I can keep it above the other children. Dragging the control works perfectly, but if a user wants to move the control outside of the grid it will allow it.
How do I keep it from leaving the bounds of the parent Grid control, here is what I have now:
private System.Windows.Point _anchorPoint;
private System.Windows.Point _currentPoint;
private bool _isInDrag;
private void UserControl_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var element = sender as FrameworkElement;
_anchorPoint = e.GetPosition(null);
if (element != null) element.CaptureMouse();
_isInDrag = true;
e.Handled = true;
}
private void UserControl_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (!_isInDrag) return;
var element = sender as FrameworkElement;
if (element != null) element.ReleaseMouseCapture();
_isInDrag = false;
e.Handled = true;
}
private void UserControl_MouseMove(object sender, MouseEventArgs e)
{
if (!_isInDrag) return;
_currentPoint = e.GetPosition(null);
UIElement container = VisualTreeHelper.GetParent(_parentGrid) as UIElement;
System.Windows.Point relativeLocation = _parentGrid.TranslatePoint(new System.Windows.Point(0, 0), container);
if (_currentPoint.X > relativeLocation.X) return;
if(_currentPoint.Y >= relativeLocation.Y)return;
_transform.X += _currentPoint.X - _anchorPoint.X;
_transform.Y += (_currentPoint.Y - _anchorPoint.Y);
RenderTransform = _transform;
_anchorPoint = _currentPoint;
}
The "relativeLocation" is always 0x0, so thats not working. Any ideas would greatly be appreciated.
*Note : I know if I changed my UserControl to a Window it would mitigate all of the issues that I am having. But to be honest, it looks great this way and I really don't want to clutter the window up. This system opens up as a dashboard that consumes the user's' entire window ( is opened on a separate window). So when you open a window here, its doesn't flow right.
I don't think you need the relativeLocation. The math can be a bit annoying to get right, though. Try this approach, it worked well when I tested it:
private void UserControl_MouseMove(object sender, MouseEventArgs e)
{
if (!_isInDrag) return;
_currentPoint = e.GetPosition(null);
//This is the change to the position that we want to apply
Point delta = new Point();
delta.X = _currentPoint.X - _anchorPoint.X;
delta.Y = _currentPoint.Y - _anchorPoint.Y;
//Calculate user control edges
var leftEdge = Margin.Left + _transform.X + delta.X;
var topEdge = Margin.Top + _transform.Y + delta.Y;
var rightEdge = Width + Margin.Left + _transform.X + delta.X;
var bottomEdge = Height + Margin.Top + _transform.Y + delta.Y;
//Set the delta to 0 if it goes over _parentGrid edges
if (leftEdge < 0) delta.X = 0;
if (topEdge < 0) delta.Y = 0;
if (rightEdge > _parentGrid.Width) delta.X = 0;
if (bottomEdge > _parentGrid.Height) delta.Y = 0;
//Apply the delta to the user control
_transform.X += delta.X;
_transform.Y += delta.Y;
RenderTransform = _transform;
_anchorPoint = _currentPoint;
}
This is a start:
Point position = _parentGrid.PointToScreen(new Point(0, 0));
PresentationSource source = PresentationSource.FromVisual(_parentGrid);
position = source.CompositionTarget.TransformFromDevice.Transform(position);
Now you have the screen coordinates of the parent grid. The call to Transform() is important as it will convert pixels to WPF device independent pixels, matching the system DPI setting.

Drag and drop TextBox?

I have a drag and drop interface in my Universal Windows App, where the user can add a textbox to the image, and drag and scale it around, as if it was a textbox in MSPaint, but it can be edited after it is placed, by double-tapping it.
I have implemented this as such:
textBox.LostFocus sets textBox.IsReadOnly = true;
textBox.DoubleTapped sets IsReadOnly back to false, so that it can drag around.
textBox.ManipulationDelta moves the textBox around.
Now I have the problem that the textBox has this rubberbanding effect going on, and that this blocks the manipulation event.
Is there a way to disable this? Or can I for example say when the mouse clicks (or finger or whatever), that it should start the manipulation event?
Code for a new TextBox:
private TextBox CreateManipulativeTextBox(string text)
{
var textBox = new TextBox
{
Text = text,
Background = new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)),
BorderBrush = new SolidColorBrush(Color.FromArgb(128, 0, 0, 0)),
Width = 150,
Height = 50,
ManipulationMode = ManipulationModes.TranslateX | ManipulationModes.TranslateY | ManipulationModes.Scale,
RenderTransform = new CompositeTransform()
};
// Doubletap gives edit possibility, tap outside loses editability
textBox.LostFocus += TextBoxOnLostFocus;
textBox.DoubleTapped += TextBoxOnDoubleTapped;
// Add manipulation events
textBox.ManipulationStarted += OnManipulationStarted;
textBox.ManipulationDelta += OnManipulationDelta;
textBox.ManipulationCompleted += OnManipulationCompleted;
return textBox;
}
Code for focus and defocus:
private void TextBoxOnDoubleTapped(object sender, DoubleTappedRoutedEventArgs doubleTappedRoutedEventArgs)
{
(sender as TextBox).IsReadOnly = false;
}
private void TextBoxOnLostFocus(object sender, RoutedEventArgs routedEventArgs)
{
(sender as TextBox).IsReadOnly = true;
}
Code for manipulation:
private void OnManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e)
{
if (sender is TextBox)
(sender as TextBox).IsReadOnly = true;
((FrameworkElement)sender).Opacity = 0.6;
}
private void OnManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
var frameworkElement = (FrameworkElement)sender;
var transform = (CompositeTransform)frameworkElement.RenderTransform;
// LEFT-RIGHT bounds
if (e.Delta.Translation.X < 0) // Going left
{
if (DrawingArea.ActualWidth / 2 + (transform.TranslateX + e.Delta.Translation.X) - frameworkElement.ActualWidth / 2 > 0)
{
// Staying inside, apply translation
transform.TranslateX += e.Delta.Translation.X;
}
else
{
// Trying to go outside, because scale sucks to work with, move image back inside
transform.TranslateX = frameworkElement.ActualWidth / 2 - DrawingArea.ActualWidth / 2;
}
}
else // Going right
{
if (DrawingArea.ActualWidth / 2 - (transform.TranslateX + e.Delta.Translation.X) +
frameworkElement.ActualWidth * (0.5 - transform.ScaleX) > 0)
{
// Staying inside, apply translation
transform.TranslateX += e.Delta.Translation.X;
}
else
{
// Trying to go outside, because scale sucks to work with, move image back inside
transform.TranslateX = frameworkElement.ActualWidth * (0.5 - transform.ScaleX) + DrawingArea.ActualWidth / 2;
}
}
// UP-DOWN bounds
if (e.Delta.Translation.Y < 0) // Going up
{
if (DrawingArea.ActualHeight / 2 + (transform.TranslateY + e.Delta.Translation.Y) - frameworkElement.ActualHeight / 2 >
0)
{
// Staying inside, apply translation
transform.TranslateY += e.Delta.Translation.Y;
}
else
{
// Trying to go outside, because scale sucks to work with, move image back inside
transform.TranslateY = frameworkElement.ActualHeight / 2 - DrawingArea.ActualHeight / 2;
}
}
else // Going down
{
if (DrawingArea.ActualHeight / 2 - (transform.TranslateY + e.Delta.Translation.Y) +
frameworkElement.ActualHeight * (0.5 - transform.ScaleY) > 0)
{
// Staying inside, apply translation
transform.TranslateY += e.Delta.Translation.Y;
}
else
{
// Trying to go outside, because scale sucks to work with, move image back inside
// transform.TranslateY = image.ActualHeight*(0.5 - transform.ScaleY) + DrawingArea.ActualHeight/2;
// Dragging down, remove image
DrawingArea.Children.Remove(frameworkElement);
}
}
// Only allow scaling when both dimensions are smaller than the drawingarea
if (frameworkElement.ActualHeight * (transform.ScaleY * e.Delta.Scale) < DrawingArea.ActualHeight &&
frameworkElement.ActualWidth * (transform.ScaleX * e.Delta.Scale) < DrawingArea.ActualWidth)
{
transform.ScaleX *= e.Delta.Scale;
transform.ScaleY *= e.Delta.Scale;
}
}
private void OnManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
((FrameworkElement)sender).Opacity = 1;
}
EDIT: This only happens with touch, when the mouse drags the item around it works.

C# Drag & Drop Multiple Images within Canvas

I've got the following code to drag and drop images inside my Canvas:
img.AllowDrop = true;
img.PreviewMouseLeftButtonDown += this.MouseLeftButtonDown;
img.PreviewMouseMove += this.MouseMove;
img.PreviewMouseLeftButtonUp += this.PreviewMouseLeftButtonUp;
private object movingObject;
private double firstXPos, firstYPos;
private void MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
// In this event, we get the current mouse position on the control to use it in the MouseMove event.
Image img = sender as Image;
Canvas canvas = img.Parent as Canvas;
firstXPos = e.GetPosition(img).X;
firstYPos = e.GetPosition(img).Y;
movingObject = sender;
// Put the image currently being dragged on top of the others
int top = Canvas.GetZIndex(img);
foreach (Image child in canvas.Children)
if (top < Canvas.GetZIndex(child))
top = Canvas.GetZIndex(child);
Canvas.SetZIndex(img, top + 1);
}
private void PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) {
Image img = sender as Image;
Canvas canvas = img.Parent as Canvas;
movingObject = null;
// Put the image currently being dragged on top of the others
int top = Canvas.GetZIndex(img);
foreach (Image child in canvas.Children)
if (top > Canvas.GetZIndex(child))
top = Canvas.GetZIndex(child);
Canvas.SetZIndex(img, top + 1);
}
private void MouseMove(object sender, MouseEventArgs e) {
if (e.LeftButton == MouseButtonState.Pressed && sender == movingObject) {
Image img = sender as Image;
Canvas canvas = img.Parent as Canvas;
double newLeft = e.GetPosition(canvas).X - firstXPos - canvas.Margin.Left;
// newLeft inside canvas right-border?
if (newLeft > canvas.Margin.Left + canvas.ActualWidth - img.ActualWidth)
newLeft = canvas.Margin.Left + canvas.ActualWidth - img.ActualWidth;
// newLeft inside canvas left-border?
else if (newLeft < canvas.Margin.Left)
newLeft = canvas.Margin.Left;
img.SetValue(Canvas.LeftProperty, newLeft);
double newTop = e.GetPosition(canvas).Y - firstYPos - canvas.Margin.Top;
// newTop inside canvas bottom-border?
if (newTop > canvas.Margin.Top + canvas.ActualHeight - img.ActualHeight)
newTop = canvas.Margin.Top + canvas.ActualHeight - img.ActualHeight;
// newTop inside canvas top-border?
else if (newTop < canvas.Margin.Top)
newTop = canvas.Margin.Top;
img.SetValue(Canvas.TopProperty, newTop);
}
}
This code allows me to drag-and-drop the Images inside the Canvas, without leaving the Canvas itself.
Now I just need to be able to do two more things:
Fix a little bug where my Mouse slips of the Image when I drag them around to fast. This happens quite often, even when I'm not even moving the dragging image around THAT fast..
Making it able to drag-and-drop multiple images at once, preferably by selecting multiple first, and then drag-and-drop the whole bunch of them while staying inside the Canvas.
PS: My previously question can be found here.
You'll want to lock the mouse on to the image to stop the cursor slipping off it Mouse.Capture (imageReference), you can release it on mouse up with Mouse.Capture (null) – Andy Feb 18 at 15:58
After using Andy's suggestion, by adding:
Mouse.Capture(img);
at the bottom of the MouseLeftButtonDown-function, and
Mouse.Capture(null);
at the bottom of the PreviewMouseLeftButtonUp-function, it works like a charm. So thanks a lot Andy!

Zoom Image in Picture Box

I am creating an application, in which user will be able to Upload an image and then Zoom in and Out the image on a particular location (current mouse pointer).
Also user should be able to drag the image to see other parts of the image when the image is zoomed.
I have implemented some functionality to achieve it but i am scaling the complete image. I want to know that how i can scale a particular portion of image, or scale the complete image and then point to that location where my current mouse pointer is placed.
Code:
private void DisplayIsdDiagram(BO.IsdDiagram IsdDiagram)
{
DoubleBuffered = true;
zoomFac = 1;
translateX = 0;
translateY = 0;
transStartX = 0f;
transStartY = 0f;
picIsdDiagram.BorderStyle = BorderStyle.Fixed3D;
bmp = new Bitmap(Image.FromStream(new MemoryStream(IsdDiagram.Image.ToArray())));
if (bmp.Width > bmp.Height)
{
ratio = (float)picIsdDiagram.Width / (float)bmp.Width;
translateRatio = (float)bmp.Width / (float)picIsdDiagram.Width;
}
else
{
ratio = (float)picIsdDiagram.Height / (float)bmp.Height;
translateRatio = (float)bmp.Height / (float)picIsdDiagram.Height;
}
//picIsdDiagram.Image = bmp;
picIsdDiagram.Refresh();
picIsdDiagram.MouseWheel += new MouseEventHandler(picIsdDiagram_MouseWheel);
}
private void picIsdDiagram_MouseWheel(object sender, MouseEventArgs e)
{
IsZooming = true;
if (e.Delta < 0)
{
if (zoomFac > 1)
zoomFac = zoomFac - (float)0.1;
}
else
{
if (zoomFac <= 5)
zoomFac = zoomFac + (float)0.1;
}
picIsdDiagram.Refresh();
IsZooming = false;
}
private void picIsdDiagram_MouseDown(object sender, MouseEventArgs e)
{
IsZooming = false;
IsMouseDown = true;
transStartX = e.X;
transStartY = e.Y;
}
private void picIsdDiagram_MouseUp(object sender, MouseEventArgs e)
{
IsZooming = false;
IsMouseDown = false;
translateX = translateX + ((e.X - transStartX) * (translateRatio / zoomFac));
translateY = translateY + ((e.Y - transStartY) * (translateRatio / zoomFac));
picIsdDiagram.Refresh();
}
private void picIsdDiagram_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
g.ScaleTransform(ratio * zoomFac, ratio * zoomFac);
if (IsZooming == false && IsMouseDown == true)
g.TranslateTransform(translateX, translateY);
g.DrawImage(bmp, 0, 0);
}
I tried to get the current mouse position from MouseHover event and tried to Translate the picture when only Zoom is done, but that is not working.
Also the Picture Box has some other multiple Picture boxes inside it, to show some representation on the big image. While scaling the Big Image, small images (inside images) should not be scaled. Although there position needs to be recalculated to show them at their real places even after zooming on the Big image.
So in above i am facing two problems:
1) To Zoom an Image at any particular location (current mouse pointer)
by scrolling.
2) To regenerate the coordinates of the sub images while
zooming and translating.
Any help that can guide me in correct direction.
Also if by any other means, i could be able to achieve this functionality.
Application : Windows
Control : Picture Box (Please suggest if any other control can be used, if not possible with this)
Language : C#
Waiting for response!
PictureEdit control provided by DevExpress 13.2

Categories