Drag Drop Picturebox - c#

I am trying to make an application in which i have 7 Pictureboxes and i want to drag drop one each time i click then move the mouse on the form. I did make it to some extend by moving the picture-box on the form but i cannot keep the original image. When i drag drop a picture box i want to drag drop just a copy not the whole picture box on the form. Any help will be greatly appreciated. Kind regards.
public Form1()
{
controller = Controller.getController();
InitializeComponent();
this.AllowDrop = true;
this.pbOR.MouseDown += pbOR_MouseUp;
}
private void pbOR_MouseDown(object sender, MouseEventArgs e)
{
downPoint = e.Location;
pbOR.Parent = this;
pbOR.BringToFront();
}
private void pbOR_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
pbOR.Left += e.X - downPoint.X;
pbOR.Top += e.Y - downPoint.Y;
}
}
private void pbOR_MouseUp(object sender, MouseEventArgs e)
{
Control c = GetChildAtPoint(new Point(pbOR.Left - 1, pbOR.Top));
if (c == null) c = this;
Point newLoc = c.PointToClient(pbOR.Parent.PointToScreen(pbOR.Location));
pbOR.Parent = c;
pbOR.Location = newLoc;
}

Related

How does it go to its first position if I don't drag the button where I want to drag it?

enter image description hereI have 9 buttons. Three are located above, 3 are located below them. All 3 buttons are on the right side. The antonyms of the words written on the buttons above are written on the buttons on the right. I would like to place the buttons with these antonyms on the buttons at the bottom. The buttons at the bottom are colored and their text is the same as the buttons on the right, but their text is not visible because it is the same as the button color. So the buttons on the bottom look like a colored box. That's what I want to do now; for example, button 1 = cold and button7 = hot. I want to place this button 7 on button 4 located below button 1, but if I want to place it on button 5 I want it to return to its original position. In the code I wrote, as soon as I press button7, it goes directly to button4, I can't try the other buttons. how can I try other buttons and return them to the first position in Visual studio form application?
enter code here
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace materyalll
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
startlocation = new Point(button7.Left, button7.Top);
startlocation2 = new Point(button8.Left, button8.Top);
startlocation3 = new Point(button9.Left, button9.Top);
}
Point location, location2, location3, startlocation, startlocation2, startlocation3;
private void button7_MouseDown(object sender, MouseEventArgs e)
{
location = e.Location;
}
private void button7_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
button7.Left += e.X - (location.X);
button7.Top += e.Y - (location.Y);
}
}
private void button7_MouseUp(object sender, MouseEventArgs e)
{
if (button7.Text == button4.Text)
button7.Location = button4.Location;
else if (button7.Text != button5.Text)
button7.Location = startlocation;
else if (button7.Text != button6.Text)
button7.Location = startlocation;
}
private void button8_MouseDown(object sender, MouseEventArgs e)
{
location2 = e.Location;
}
private void button8_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
button8.Left += e.X - (location2.X);
button8.Top += e.Y - (location2.Y);
}
}
private void button8_MouseUp(object sender, MouseEventArgs e)
{
if (button8.Text == button5.Text)
button8.Location = button5.Location;
else if (button8.Text != button4.Text)
button8.Location = startlocation2;
else if (button8.Text != button6.Text)
button8.Location = startlocation2;
}
private void button9_MouseDown(object sender, MouseEventArgs e)
{
location3 = e.Location;
}
private void button9_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
button9.Left += e.X - (location3.X);
button9.Top += e.Y - (location3.Y);
}
}
private void button9_MouseUp(object sender, MouseEventArgs e)
{
if (button9.Text == button6.Text)
button9.Location = button6.Location;
else if (button9.Text != button4.Text)
button9.Location = startlocation3;
else if (button9.Text != button5.Text)
button9.Location = startlocation3;
}
}
}
Store the original location of the Button in the .Tag property of the Button itself. When the user releases the mouse, see if the RECTANGLES of the correct target button and the current button INTERSECT. If they don't, snap back to the stored location in the Tag; otherwise snap to the location of the correct button.
Here it is with button7:
public Form1()
{
InitializeComponent();
button7.Tag = button7.Location;
button8.Tag = button8.Location;
button9.Tag = button9.Location;
}
private void button7_MouseUp(object sender, MouseEventArgs e)
{
if (button7.Bounds.IntersectsWith(button4.Bounds)) {
button7.Location = button4.Location;
}
else
{
button7.Location = (Point)button7.Tag;
}
}
The code for the other two buttons would be very similar.
Try something like this:
Dictionary<string, Point> originalPoints = new Dictionary<string, Point>();
originalPoints.Add(nameof(button1), new Point(button1.Left, button1.Top));
// repeat this for all buttons
void SetToOriginalPosition(Button button)
{
Point p = originalPoints[nameof(button)];
button.Left = p.X;
button.Top = p.Y;
}

How to scrollUp or down in panel with Mouse_Wheel Events without using Scrollbar Winforms

Example:
I have a Panel or flowLayoutpanel so I want to scroll look into items without using scrollbar, instead I want to use MouseWheel
So I was wondering is there any way that you can scroll up or down in a panel or flowLayoutPanel
Without use 'Auto Scroll= true' instead I want to moveViewPanel up or down when mouse scrolled.
If you get what I mean
These are some code that I used with but seemed not to work at all
--Sameple1
void Panel2_mWheel(object sender, MouseEventArgs e)
{
//Get cursor position
Point mousePoint = new Point(e.X, e.Y);
//Change to the location of the form of this form
mousePoint.Offset(this.Location.X, this.Location.Y);
if (panel2.RectangleToScreen(panel2.DisplayRectangle).Contains(mousePoint))
{
Console.WriteLine("Contain");
panel2.AutoScrollPosition = new Point(0, panel2.VerticalScroll.Value - e.Delta);
}
}
--Sample2
Panel.MouseEnter += C_MouseEnter;
void Panel_MouseEnter(object sender, EventArgs e)
{
c.Focus();
}
--sample3
panel.MouseWheel += pn_MouseWheel;
private void pn_MouseWheel(object sender, MouseEventArgs e)
{
int deltaScroll = 10;
if (e.Delta > 0)
{
if (pnlContain.VerticalScroll.Value - deltaScroll >= pnlContain.VerticalScroll.Minimum)
pnlContain.VerticalScroll.Value -= deltaScroll;
else
pnlContain.VerticalScroll.Value = pnlContain.VerticalScroll.Minimum;
}
else
{
if (pnlContain.VerticalScroll.Value + deltaScroll <= pnlContain.VerticalScroll.Maximum)
pnlContain.VerticalScroll.Value += deltaScroll;
else
pnlContain.VerticalScroll.Value = pnlContain.VerticalScroll.Maximum;
}
--sample 4
panel_wheel(object sender, MouseEventArgs e)
{
if(e.OldValue>e.NewValue)
{
//Scroll up Do stuff
}
else
{
//Scroll down Do stuff
}
}
Anyone help me please!!

Drag'n Drop : tell the sender when drop occurs

I'm using c# 3.5 / winforms
On my form, I have 2 picturebox PB1 and PB2 (and lots of others controls), in a panel.
The user can drag PB1 to PB2. But he can also cancel the drop by release the left button anywhere on the form or outside the form.
PB1 can be dragged a fixed number of times. When the drag start, I decrease a variable in PB1 and if it reach 0, the PB became invisible.
But if the user cancel the drag, PB1 must know that to increase the variable and set the visibility of PB1.
My problem is : how PB1 can know when a drag is canceled (or actually, dropped, even on a valid control) ? Remember that the user can release the drag outside of the form, so I can't use the Drop event on the form. I try the GiveFeedback and the QueryContinueDrag events, but they are fired as long as the drag continue, but not when it stop.
Some code :
class COPGOJetonImage
{
private PictureBox PB1;
public COPGOJetonImage()
{
PB1 = new PictureBox();
//here I initialize PB1
((Control)PB1).AllowDrop = true; //in case of
PB1.MouseDown += OnMouseDown;
}
public void OnMouseDown(object sender, MouseEventArgs ev)
{
PB1.DoDragDrop(PB1.Image, DragDropEffects.Copy);
}
}
"there are 1 to 4 valid targets."
In this example we are dragging pictureBox1, and pictureBox2 thru pictureBox5 are the valid drop targets. We create a DataObject with a custom name to encapsulate pictureBox1 during the drag/drop operation. In the drop targets, we only allow a drop if the custom name is present in the thing being dragged. This ensures we only get a DragDrop event from pictureBox1 itself, and we know it's safe to decrement our drop counter. We can retrieve pictureBox1 back from the DataObject and change its state so that it can no longer be dropped:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private int DropsLeft = 5;
private string DataFormatName = "YourUniqueDataFormatNameHere";
private void Form1_Load(object sender, EventArgs e)
{
pictureBox1.MouseMove += PictureBox1_MouseMove;
PictureBox[] pbs = new PictureBox[] { pictureBox2, pictureBox3, pictureBox4, pictureBox5 };
foreach (PictureBox pb in pbs)
{
pb.AllowDrop = true;
pb.DragEnter += Pb_DragEnter;
pb.DragDrop += Pb_DragDrop;
}
}
private void PictureBox1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
DataObject data = new DataObject(DataFormatName, pictureBox1);
pictureBox1.DoDragDrop(data, DragDropEffects.Copy);
}
}
private void Pb_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormatName))
{
e.Effect = DragDropEffects.All;
}
else
{
e.Effect = DragDropEffects.None;
}
}
private void Pb_DragDrop(object sender, DragEventArgs e)
{
DropsLeft--;
// retrieve the data
PictureBox pb = (PictureBox)e.Data.GetData(DataFormatName);
if (DropsLeft == 0)
{
MessageBox.Show("No more drops left!");
pb.Enabled = false;
pb.BackColor = Color.Red; // for visual effect
}
}
}

Separating mouse down and mouse click events

I have two events wired to a control. A mouse click event plays an audio file. A drag event made up from mouse down, mouse move and mouse up drags the control vertically. By dragging the control vertically the control get assigned a different song.
The problem I have is that when I drag the control the music plays. I do not want this since this is a dragging operation.
Music should play only when control is clicked and note moved.
I think that setting boundaries, e.g. when control moves only 5 pixels play sound otherwise drag control should solve the problem but I tried to create them unsuccessfully.
Can you please guide how to solve this problem preferably with code snippets.
Thank You.
The Drag
int Locked_yLoc; int index;
private void StartDrag(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
sp1.SoundLocation = this.pitch + ".wav";
sp1.Play();
tm1.Interval = 100 * this.noteDuration;
tm1.Start();
isDragging = true;
pitch = e.Y;
this.Location = new Point(this.Location.X, pitch);
}
}
private void StopDrag(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
isDragging = false;
this.Location = new Point(this.Location.X, Locked_yLoc);
pitch = index;
//lbl8.Text = pitch.ToString();
}
}
private void OnDrag(object sender, MouseEventArgs e)
{
if (isDragging)
{
this.Top = this.Top + (e.Y - pitch);
Locked_yLoc = (int)Math.Round((this.Top + (e.Y - pitch)) / 10.0) * 10;
for (int i = 0; i < yLocation.Length; i++)
{
if (Locked_yLoc == yLocation[i])
{
index = CorrPitch[i];
}
}
}
}
The Click
private void MusicNote_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
sp1.SoundLocation = this.pitch + ".wav";
sp1.Play();
tm1.Interval = 100 * this.noteDuration;
tm1.Start();
}
}

Manipulating drag and drop images in windows forms c#

I am trying to write a program which will allow a user to drag and drop images into the program and then be able to select the image, move it about, re-size it, crop it etc.
So far I have created a windows form which consists of a panel. A user can drag a picture file onto the panel and a picturebox will be created at the coordinates of the mouse when it is dropped and an image is loaded in the picturebox. I can add several images in this fashion.
Now I want to allow the user to manipulate and move about the images that they have dropped into the panel.
I have tried searching for solutions but cant seem to find an answer which I understand.
Any help is much appreciated..
This is my current code
private void panel1_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.All;
}
private void panel1_DragDrop(object sender, DragEventArgs e)
{
String[] imagePaths = (String[])e.Data.GetData(DataFormats.FileDrop);
foreach (string path in imagePaths)
{
Point point = panel1.PointToClient(Cursor.Position);
PictureBox pb = new PictureBox();
pb.ImageLocation = path;
pb.Left = point.X;
pb.Top = point.Y;
panel1.Controls.Add(pb);
//g.DrawImage(Image.FromFile(path), point);
}
}
You can get the mouse position when the user initially clicks and then track the mouse position in the PictureBox's MouseMove event. You can attach these handlers to multiple PictureBoxes.
private int xPos;
private int yPos;
private void pb_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
xPos = e.X;
yPos = e.Y;
}
}
private void pb_MouseMove(object sender, MouseEventArgs e)
{
PictureBox p = sender as PictureBox;
if(p != null)
{
if (e.Button == MouseButtons.Left)
{
p.Top += (e.Y - yPos);
p.Left += (e.X - xPos);
}
}
}
For dynamic PictureBoxes you can attach the handlers like this
PictureBox dpb = new PictureBox();
dpb.MouseDown += pb_MouseDown;
dbp.MouseMove += pb_MouseMove;
//fill the rest of the properties...

Categories