Drag multiple selected controls - c#

I have on a WinForms Form a UserControl, of which multiple instances can be created dynamically. If I select it, I can drag it. Now, I want, if I select multiple UserControls (with ctrl + button click), to be able to drag all of them at the same time.
Can I do that like I did for one UserControl?
What I have tried until now:
// For dragging I use this method and also I have
// overridden MouseUp,MouseDown,MouseMove from .net
public void StartDrag()
{
dragging = true;
Point p = PointToClient(Cursor.Position);
dragStart = new Point(Math.Max(0, p.X), Math.Max(0, p.Y));
buttondrag.Capture = true;
}
private void Usercontrol1_SelectedChanged(object sender, EventArgs e)
{
if (((UserControl)sender).Selected)
{
if (SelectedUserControl.Count > 1)
{
foreach (UserControl c in panel1.Controls)
{
c.StartDrag();
}
}
}
}

// put your controls in the panel, and use this class.
class ControlMover
{
public enum Direction
{
Any,
Horizontal,
Vertical
}
public static void Init(Control control)
{
Init(control, Direction.Any);
}
public static void Init(Control control, Direction direction)
{
Init(control, control, direction);
}
public static void Init(Control control, Control container, Direction direction)
{
bool Dragging = false;
Point DragStart = Point.Empty;
control.MouseDown += delegate(object sender, MouseEventArgs e)
{
Dragging = true;
DragStart = new Point(e.X, e.Y);
control.Capture = true;
};
control.MouseUp += delegate(object sender, MouseEventArgs e)
{
Dragging = false;
control.Capture = false;
};
control.MouseMove += delegate(object sender, MouseEventArgs e)
{
if (Dragging)
{
if (direction != Direction.Vertical)
container.Left = Math.Max(0, e.X + container.Left - DragStart.X);
if (direction != Direction.Horizontal)
container.Top = Math.Max(0, e.Y + container.Top - DragStart.Y);
}
};
}
}
public Form1()
{
InitializeComponent();
ControlMover.Init(this.panel1);
ControlMover.Init(this.panel1, ControlMover.Direction.Vertical);
}

If you want the program to activate when ctrl + key is pressed then you will need to look at key hooks, and then set up some code in the key down event telling the program to select all items.
This is quite advanced and difficult to do if your new to key hooks, but here's a link for key hooks.
Good luck!
http://www.codeproject.com/Articles/19004/A-Simple-C-Global-Low-Level-Keyboard-Hook

Related

WPF DragMove() causes issues

I'm trying to figure out if there's an elegant solution to the problem I've been faced with.
So basically, I designed a borderless loading splash screen which is completely movable via dragging. I find that this happens if the splash screen gets hidden via Hide(), then displays a window via ShowDialog() with the owner set to the splash screen. Things get extremely buggy, but only if you're in mid-drag (with left mouse button down). You become unable to click or move anything, even Visual Studio becomes unresponsive unless you explicitly alt-tab out of the application.
Considering I know when I'm going to spawn the window, I was thinking maybe there'd be a way to cancel the DragMove operation, but I'm having no luck. What I've figured out is that DragMove is synchronous, so I'd guess it'd have to be cancelled from a different thread or in an event callback.
Edit:
public partial class Window_Movable : Window
{
public Window_Movable()
{
InitializeComponent();
}
public Boolean CanMove { get; set; } = true;
private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (CanMove == false)
return;
Task.Factory.StartNew(() => {
System.Threading.Thread.Sleep(1000);
Dispatcher.Invoke(() => {
Hide();
new Window_Movable() {
Title = "MOVABLE 2",
CanMove = false,
Owner = this
}.ShowDialog();
});
});
DragMove();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Console.WriteLine("DING");
}
}
I had the same problem and found out that DragMove() method is a problem.
https://groups.google.com/forum/#!topic/wpf-disciples/7OcuXrf2whc
To solve I decided to refuse from using it and implement moving logic.
I've combined some solutions from
https://www.codeproject.com/Questions/284995/DragMove-problem-help-pls
and
C# WPF Move the window
private bool _inDrag;
private Point _anchorPoint;
private bool _iscaptured;
private void AppWindowWindowOnMouseMove(object sender, MouseEventArgs e)
{
if (!_inDrag)
return;
if (!_iscaptured)
{
CaptureMouse();
_iscaptured = true;
}
var mousePosition = e.GetPosition(this);
var mousePositionAbs = new Point
{
X = Convert.ToInt16(_appWindowWindow.Left) + mousePosition.X,
Y = Convert.ToInt16(_appWindowWindow.Top) + mousePosition.Y
};
_appWindowWindow.Left = _appWindowWindow.Left + (mousePositionAbs.X - _anchorPoint.X);
_appWindowWindow.Top = _appWindowWindow.Top + (mousePositionAbs.Y - _anchorPoint.Y);
_anchorPoint = mousePositionAbs;
}
private void AppWindowWindowOnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (_inDrag)
{
_inDrag = false;
_iscaptured = false;
ReleaseMouseCapture();
}
}
private void AppWindowWindowOnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
_anchorPoint = e.GetPosition(this);
_anchorPoint.Y = Convert.ToInt16(_appWindowWindow.Top) + _anchorPoint.Y;
_anchorPoint.X = Convert.ToInt16(_appWindowWindow.Left) + _anchorPoint.X;
_inDrag = true;
}
I've spend all yesterday evening and find a more hacky but more functional solution. Which support Maximized state and not require manual coordinate calculation.
private bool _mRestoreForDragMove;
private void OnAppWindowWindowOnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.ClickCount == 2)
{
if (_appWindowWindow.ResizeMode != ResizeMode.CanResize &&
_appWindowWindow.ResizeMode != ResizeMode.CanResizeWithGrip)
{
return;
}
_appWindowWindow.WindowState = _appWindowWindow.WindowState == WindowState.Maximized
? WindowState.Normal
: WindowState.Maximized;
}
else
{
_mRestoreForDragMove = _appWindowWindow.WindowState == WindowState.Maximized;
SafeDragMoveCall(e);
}
}
private void SafeDragMoveCall(MouseEventArgs e)
{
Task.Delay(100).ContinueWith(_ =>
{
Dispatcher.BeginInvoke((Action)
delegate
{
if (Mouse.LeftButton == MouseButtonState.Pressed)
{
_appWindowWindow.DragMove();
RaiseEvent(new MouseButtonEventArgs(e.MouseDevice, e.Timestamp, MouseButton.Left)
{
RoutedEvent = MouseLeftButtonUpEvent
});
}
});
});
}
private void OnMouseMove(object sender, MouseEventArgs e)
{
if (_mRestoreForDragMove)
{
_mRestoreForDragMove = false;
var point = PointToScreen(e.MouseDevice.GetPosition(this));
_appWindowWindow.Left = point.X - (_appWindowWindow.RestoreBounds.Width * 0.5);
_appWindowWindow.Top = point.Y;
_appWindowWindow.WindowState = WindowState.Normal;
_appWindowWindow.DragMove();
SafeDragMoveCall(e);
}
}
private void OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
_mRestoreForDragMove = false;
}
The thing is to send LeftMouseButtonUp event after a short delay to avoid blocking from DragMove()
Sources for last solve:
DragMove() and Maximize
C# WPF - DragMove and click
And one more completely different solution. To make a window movable you can use CaptionHeight of WindowChrome.
i.e.
var windowChrome =
WindowChrome.GetWindowChrome(appWindow.Window);
windowChrome.CaptionHeight = MainWindowToolbar.Height;
WindowChrome.SetWindowChrome(appWindow.Window, windowChrome);
but you should also set attached property WindowChrome.IsHitTestVisibleInChrome="True" for all controls in the window.

Mouse Control, I am looking to have a pictureBox follow the mouse cursor at a certain rate

A bit lost here with first time accessing cursor's properties for movement.
I want a pictureBox(player) to move slowly towards the mouse cursor after fst_click(bool) is enabled. I have tried a multitude of methods but have had no success. I have tried cases but my return methods are inoperable any help on this?
I though maybe a mouse listener of some sort, to update the location of the mouse and depending on timer speed move towards the location but paths are definitely not my strong point.
private int _x;
private int _y;
private bool MRight = false;
private bool MLeft = false;
private bool MUp = false;
private bool MDown = false;
bool fst_click = false;
private Position _objPosition;
public Form1()
{
InitializeComponent();
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
clicking = true;
}
public void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Space)
{ clicking = true; }
}
I removed the incorrect case statement and added a different bool. This statement did switch between 4 cases W, A, S, D but the player location couldn't be updated smoothly?
I also added a timer to attempt to insert a boolean that would create smooth movement but again I couldn't relate to the players' location?
public void tmrMoving_Tick(object sender, EventArgs e)
{
if (clicking == true)
{
player.Location = Cursor.Position;
clicking = false;
}
}
private void Form1_MouseMoveHandler(object sender, MouseEventArgs e)
{
//Point mousePoint = new Point(player.Location.X, player.Location.Y);
}
Update
I have added the new coding below, if there are any ideas on how to repair this as I get no functionality from it. The cursor needs to be moving towards the clicked position at a certain speed, the commented out code is a failed attempt and I am looking to replace it.
namespace games1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_MouseClick(object sender, MouseEventArgs e)
{
tmrMoving.Enabled = true;
Invalidate();
}
private void tmrMoving_Tick(object sender, EventArgs e)
{
var xdiff = Cursor.Position.X - player.Location.X;
var ydiff = Cursor.Position.Y - player.Location.Y;
var diff = Math.Sqrt(xdiff + ydiff);
// diff = ydiff / 10;
// diff = xdiff / 10;
// xdiff = player.Location.X;
// ydiff = player.Location.Y;
}
}
}

C# drag controls around a panel

i am developing a system which allow user to drag objects around within a same panel, i went through some research and founds that i should use mouse events like mouse_up, mouse_down and mouse_move.
The the program will generate 3 picturebox and allow the user to drag around the every picturebox within the panel, but the program i code did not work perfectly as when i drag over a picturebox, the picturebox will move, but not according to my mouse cursor location, it is somewhere else, besides, when dragging, there is picturebox shadows in the panel, i've tried those update(),refresh(), and invalidate() but it seems not useful for me. Below are my codes, thanks for helping
public partial class Form1 : Form
{
List<PictureBox> pictureBoxList = new List<PictureBox>();
private bool isDragging = false;
public Form1()
{
InitializeComponent();
for (int i = 0; i < 3; i++)
{
PictureBox picture = new PictureBox
{
Name = "pictureBox" + i,
Size = new Size(20, 20),
Location = new Point(i * 40, i * 40),
BorderStyle = BorderStyle.FixedSingle,
SizeMode = PictureBoxSizeMode.Zoom,
ImageLocation = "A.jpg"
};
pictureBoxList.Add(picture);
foreach (PictureBox p in pictureBoxList)
{
p.MouseDown += new MouseEventHandler(c_MouseDown);
p.MouseMove += new MouseEventHandler(c_MouseMove);
p.MouseUp += new MouseEventHandler(c_MouseUp);
pnlDisplayImage.Controls.Add(p);
pnlDisplayImage.Refresh();
}
}
}
void c_MouseDown(object sender, MouseEventArgs e)
{
isDragging = true;
}
void c_MouseMove(object sender, MouseEventArgs e)
{
if (isDragging == true) {
Control c = sender as Control;
for (int i = 0; i < pictureBoxList.Count(); i++)
{
if (c.Equals(pictureBoxList[i]))
{
pictureBoxList[i].Location = new Point(e.X, e.Y);
}
}
}
}
void c_MouseUp(object sender, MouseEventArgs e)
{
PictureBox c = sender as PictureBox;
isDragging = false;
for (int i = 0; i < pictureBoxList.Count(); i++) {
if (c.Equals(pictureBoxList[i])){
pictureBoxList[i].Location = new Point(e.X, e.Y);
}
}
}
private void pnlDisplayImage_Paint(object sender, PaintEventArgs e)
{
foreach (PictureBox p in pictureBoxList)
{
pnlDisplayImage.Controls.Add(p);
}
}
}
Finally I've found what are the problems that caused my program not running as my expectations. The main problem is that I accidentally put the foreach loop inside the for loop which I used to create pictureBox, this problem caused the pictureBox comes out some shadows effect while dragging during run time due to there are few same pictureBox. Also, I have change a little bit of the codes and it now run as what I expected. Below are the code that I want for answer.
public partial class Form1 : Form
{
List<PictureBox> pictureBoxList = new List<PictureBox>();
private bool isDragging = false;
Point move;
public Form1()
{
InitializeComponent();
for (int i = 0; i < 3; i++)
{
PictureBox picture = new PictureBox
{
Name = "pictureBox" + i,
Size = new Size(20, 20),
Location = new Point(i * 40, i * 40),
BorderStyle = BorderStyle.FixedSingle,
SizeMode = PictureBoxSizeMode.Zoom,
ImageLocation = "A.jpg"
};
pictureBoxList.Add(picture);
}
foreach (PictureBox p in pictureBoxList)
{
p.MouseDown += new MouseEventHandler(c_MouseDown);
p.MouseMove += new MouseEventHandler(c_MouseMove);
p.MouseUp += new MouseEventHandler(c_MouseUp);
pnlDisplayImage.Controls.Add(p);
pnlDisplayImage.Refresh();
}
}
void c_MouseDown(object sender, MouseEventArgs e)
{
Control c = sender as Control;
isDragging = true;
move = e.Location;
}
void c_MouseMove(object sender, MouseEventArgs e)
{
if (isDragging == true) {
Control c = sender as Control;
for (int i = 0; i < pictureBoxList.Count(); i++)
{
if (c.Equals(pictureBoxList[i]))
{
pictureBoxList[i].Left += e.X - move.X;
pictureBoxList[i].Top += e.Y - move.Y;
}
}
}
}
void c_MouseUp(object sender, MouseEventArgs e)
{
isDragging = false;
}
}
Try something like (it's custom control with overrides, but should be easy to convert to events):
private bool _isMoved = false; // true if move mode on
private Point _pointMove = new Point(0); // for moving
protected override void OnMouseDown(MouseEventArgs e)
{
// if left button pressed
if(e.Button == MouseButtons.Left)
{
_pointMove.X = e.X;
_pointMove.Y = e.Y;
_isMoved = true;
Cursor = Cursors.SizeAll;
Capture = true;
}
base.OnMouseDown (e);
}
protected override void OnMouseUp(MouseEventArgs e)
{
// if move mode on
if(_isMoved)
{
_isMoved = false;
Cursor = Cursors.Default;
Capture = false;
}
base.OnMouseUp (e);
}
protected override void OnMouseMove(MouseEventArgs e)
{
// if move mode on
if (_isMoved)
{
Left += e.X - _pointMove.X;
Top += e.Y - _pointMove.Y;
}
base.OnMouseMove (e);
}

WPF C# PreviewDrop/Drop event not fired ( With dragadorner)

I assume that previewdrop/drop events fired when it detect a drag target with an element as a drop target . In this case , my drop target is a textbox and my drag target is a label. Both of them are dynamically created from DB . I am using DragAdorner to clone the element that i am dragging , before implementing the DragAdorner , my DnD works well but after i use the dragadorner , it won't work . And i notice my previewdrop event is not firing when i try to debug .
Here are my codes :
tbox.Drop += new DragEventHandler(tbox_PreviewDrop); // text box , Drop Target
tbox.DragOver += new DragEventHandler(tbox_DragOver);
Label lbl = new Label(); // Label , Drag Target
lbl.Content = s;
lbl.Width = Double.NaN;
lbl.Height = 40;
lbl.FontSize = 19;
lbl.PreviewMouseDown += new MouseButtonEventHandler(lbl_MouseDown);
lbl.PreviewMouseMove += new MouseEventHandler(lbl_MouseMove);
lbl.PreviewGiveFeedback += new GiveFeedbackEventHandler(lbl_GiveFeedback);
private void lbl_MouseDown(object sender, MouseButtonEventArgs e)
{
startPoint = e.GetPosition(this);
// Mouse.OverrideCursor = Cursors.None;
}
private void lbl_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
// Mouse.OverrideCursor = Cursors.None;
var source = sender as UIElement;
Label lbl = sender as Label;
Point current = e.GetPosition(this);
Vector diff = startPoint - current;
if (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance)
{
adorner = new DragAdorner(lbl, e.GetPosition(lbl));
AdornerLayer.GetAdornerLayer(lbl).Add(adorner);
var dragData = new DataObject(this);
DragDrop.DoDragDrop(source, dragData, DragDropEffects.Copy);
AdornerLayer.GetAdornerLayer(lbl).Remove(adorner);
}
startPoint = current;
}
}
private void lbl_GiveFeedback(object sender, GiveFeedbackEventArgs e)
{
if (adorner != null)
{
Label lbl = sender as Label;
var pos = lbl.PointFromScreen(GetMousePosition());
adorner.UpdatePosition(pos);
e.Handled = true;
}
}
private void tbox_PreviewDrop(object sender, DragEventArgs e)
{
(sender as TextBox).Text = string.Empty; // Empty the textbox from previous answer.
(sender as TextBox).Background = Brushes.White;
e.Effects = DragDropEffects.Move;
e.Handled = true;
}
private void tbox_DragOver(object sender, DragEventArgs e)
{
e.Handled = true;
e.Effects = DragDropEffects.Move;
}
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool GetCursorPos(ref Win32Point pt);
[StructLayout(LayoutKind.Sequential)]
internal struct Win32Point
{
public Int32 X;
public Int32 Y;
};
public static Point GetMousePosition()
{
Win32Point w32Mouse = new Win32Point();
GetCursorPos(ref w32Mouse);
return new Point(w32Mouse.X, w32Mouse.Y);
}
private Point startPoint;
private DragAdorner adorner;
And the adorner class file :
public class DragAdorner : Adorner {
public DragAdorner(UIElement adornedElement, Point offset)
: base(adornedElement) {
this.offset = offset;
vbrush = new VisualBrush(AdornedElement);
//vbrush.Opacity = .7;
}
public void UpdatePosition(Point location) {
this.location = location;
this.InvalidateVisual();
}
protected override void OnRender(DrawingContext dc) {
var p = location;
p.Offset(-offset.X, -offset.Y);
dc.DrawRectangle(vbrush, null, new Rect(p, this.RenderSize));
}
private Brush vbrush;
private Point location;
private Point offset;
}
I seen http://www.adorkable.us/books/wpf_control_development.pdf ( page 103 ) but its way too complicated for me as i am a newbie .
It is because of my GiveFeedBack event that is in conflict with other events?
Since your DragAdorner is always under your cursor, it will be the object receiving the drop. If you set IsHitTestVisible = false; in the constructor for the Adorner, it should fix this.
Even though you haven't set AllowDrop on the Adorner, since it is under the cursor, it will intercept the drop attempt. But since it doesn't accept drop, it will just cancel it.
Update
The other issue is that you are setting the allowed effects in your drag operation to DragDropEffects.Copy, but in the DragOver and Drop handlers, you're trying to do a DragDropEffects.Move. This won't work, as those are not the same operation. These must match. If you want to enable both operations on drag, you can specify both with a bitwise or:
DragDrop.DoDragDrop(source, dragData, DragDropEffects.Copy | DragDropEffects.Move);
Update 2
If you want to drop anything other than a string onto a TextBox, you have to use the PreviewDrop and PreviewDragOver events. Otherwise, the TextBox's default handling will ignore anything else. So it would look like this:
tbox.PreviewDrop += new DragEventHandler(tbox_PreviewDrop);
tbox.PreviewDragOver += new DragEventHandler(tbox_DragOver);
Try setting background color for your label and see if it will work properly.

DragDrop to move a picture box at run time

I have a PictureBox called pic, placed inside another PictureBox called picTrack.
My goal is to be able to let the user, at run time, change the position of pic by draging it.
This is what I have so far:
int x_offset = 0; // any better to do this without having a global variable?
int y_offset = 0;
void pic_MouseDown(object sender, MouseEventArgs e)
{
PictureBox me = (PictureBox)sender;
x_offset = me.Left - e.X;
y_offset = me.Top - e.Y;
}
void pic_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
PictureBox me = (PictureBox)sender;
me.Left = e.X + x_offset;
me.Top = e.Y + y_offset;
picTrack.Invalidate();
}
}
This code only works at a very basic level. I have 2 problems with it:
1.) picTrack is not updated if the user does not let go of the mouse button. Ghost images of pic can be seen while pic is getting moved around (it's like pic is having a tail).
2.) pic is "giggling" (i.e. rapidly shaking left and right, up and down, around its location).
How should I solve these 2 problems and create a more smooth drag & drop? Thanks.
Here this actually works, I've written quite a few dragging things before.. it may not be perfect but this should give you something to work with.
Point dragPoint = Point.Empty;
bool dragging = false;
private void pic_MouseDown(object sender, MouseEventArgs e)
{
dragging = true;
dragPoint = new Point(e.X, e.Y);
}
private void pic_MouseMove(object sender, MouseEventArgs e)
{
if (dragging)
pic.Location = new Point(pic.Location.X + e.X - dragPoint.X, pic.Location.Y + e.Y - dragPoint.Y);
}
private void pic_MouseUp(object sender, MouseEventArgs e)
{
dragging = false;
}
See, if you were dragging a local picture that you were just rendering yourself, this wouldn't be right.. but since you are moving a control after you move it, the new move coordinates are relative to the control. Therefore, you do not need to update dragPoint to the last position on move. If you were just moving a shape/image you were rendering OnPaint, you'd have to do update the drag point each movement.
There's one improvement you could make, if desired, which is to only start dragging if the user moves the cursor a certain distance D. For example, something like this:
Point dragPoint = Point.Empty;
bool dragging = false;
bool mouseDown = false;
private void pic_MouseDown(object sender, MouseEventArgs e)
{
mouseDown = true;
dragPoint = new Point(e.X, e.Y);
}
private void pic_MouseMove(object sender, MouseEventArgs e)
{
int deltaX = e.X - dragPoint.X;
int deltaY = e.Y - dragPoint.Y;
if (!dragging && mouseDown && deltaX * deltaX + deltaY * deltaY > 100)
dragging = true;
if (dragging)
pic.Location = new Point(pic.Location.X + deltaX, pic.Location.Y + deltaY);
}
private void pic_MouseUp(object sender, MouseEventArgs e)
{
dragging = false;
mouseDown = false;
}
Which checks if the user has moved the mouse 10 pixels (sqrt of 100).
If you don't want a global, you could try implementing your own behavior system and creating a reusable piece of code that you can attach to things you want to move. Something like this:
public class Behavior<T> where T : class
{
public T AssociatedObject
{
get;
private set;
}
public Behavior(T associatedObject)
{
this.AssociatedObject = associatedObject;
}
public virtual void Attach() { }
public virtual void Detach() { }
}
public class DragBehavior : Behavior<Control>
{
Point dragPoint = Point.Empty;
bool dragging = false;
bool mouseDown = false;
public DragBehavior(Control c) : base(c)
{
}
public override void Attach()
{
AssociatedObject.MouseDown += new MouseEventHandler(control_MouseDown);
AssociatedObject.MouseMove += new MouseEventHandler(control_MouseMove);
AssociatedObject.MouseUp += new MouseEventHandler(control_MouseUp);
}
private void control_MouseUp(object sender, MouseEventArgs e)
{
dragging = false;
mouseDown = false;
}
private void control_MouseMove(object sender, MouseEventArgs e)
{
int deltaX = e.X - dragPoint.X;
int deltaY = e.Y - dragPoint.Y;
if (mouseDown && deltaX * deltaX + deltaY * deltaY > 100)
dragging = true;
if (dragging)
AssociatedObject.Location = new Point(AssociatedObject.Location.X + deltaX, AssociatedObject.Location.Y + deltaY);
}
private void control_MouseDown(object sender, MouseEventArgs e)
{
mouseDown = true;
dragPoint = new Point(e.X, e.Y);
}
public override void Detach()
{
AssociatedObject.MouseDown -= new MouseEventHandler(control_MouseDown);
AssociatedObject.MouseMove -= new MouseEventHandler(control_MouseMove);
AssociatedObject.MouseUp -= new MouseEventHandler(control_MouseUp);
}
}
public partial class Form1 : Form
{
DragBehavior dragger;
public Form1()
{
InitializeComponent();
DoubleBuffered = true;
dragger = new DragBehavior(pic);
dragger.Attach();
}
}
Maybe that is better than "creating a global variable" (or more like creating a member variable in your form. =)
Try this
int x_offset = 0; // any better to do this without having a global variable?
int y_offset = 0;
private void pic_MouseDown(object sender, MouseEventArgs e)
{
PictureBox me = (PictureBox)sender;
x_offset = e.X;
y_offset = e.Y;
}
private void pic_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
PictureBox me = (PictureBox)sender;
me.Left = e.X + me.Left - x_offset;
me.Top = e.Y + me.Top - y_offset;
}
}

Categories

Resources