How to move a PictureBlock build dynamically - c#

I haven't found a similar question but maybe I haven't found the good keys word, my apologies if there is one.
It's my first question on this website so please tell me if I should ask my question differently! :)
I'm trying to create some pictureblock in a panel thanks to a button and drag and drop them but I don't know how to call the pictureBlock by clicking on it
I tried this, I'm able to create the block by clicking on a button and I'm able the move the last block created but I can't move other blocks.
I tried many solutions but I don't understand how to call the pictureblock i clicked on instead of calling "structures[i]"
Thank you for your help!
form 1 :
private void button1_Click(object sender, EventArgs e)
{
//ajout_panel1();
ajout_panelI();
}
private void pictureBox_Click(object sender, MouseEventArgs e)
{
pictureBox_MouseDown(this.structures[i], e);
pictureBox_MouseMove(this.structures[i], e);
}
private void pictureBox_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
MouseDownLocation = e.Location;
}
}
private void pictureBox_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
this.structures[i-1].Left = e.X + this.structures[i-1].Left - MouseDownLocation.X;
this.structures[i-1].Top = e.Y + this.structures[i-1].Top - MouseDownLocation.Y; }
}
}
Form 1 designer:
private void ajout_panelI()
{
System.Windows.Forms.PictureBox newbox = new System.Windows.Forms.PictureBox();
this.structures.Add(newbox);
panel1.SuspendLayout();
SuspendLayout();
panel1.Controls.Add(this.structures[i]);
this.structures[i].BackColor = System.Drawing.SystemColors.GradientActiveCaption;
this.structures[i].Location = new System.Drawing.Point(pos_x, pos_y);
this.structures[i].Name = pic_name();
this.structures[i].Size = new System.Drawing.Size(200, 100);
this.structures[i].TabIndex = 0;
this.structures[i].MouseDown += new System.Windows.Forms.MouseEventHandler(this.pictureBox_MouseDown);
this.structures[i].MouseMove += new System.Windows.Forms.MouseEventHandler(this.pictureBox_MouseMove);
this.structures[i].Paint += new System.Windows.Forms.PaintEventHandler(this.panel2_Paint_1);
panel1.ResumeLayout(false);
ResumeLayout(false);
pos_y = pos_y + 150;
i++;
}
public System.Windows.Forms.Panel panel1;
private System.Windows.Forms.PictureBox panel2;
private System.Windows.Forms.Panel panel3;
private System.Windows.Forms.Button button1;
public int i = 0;
private int pos_x =30;
private int pos_y =30;
private List<System.Windows.Forms.PictureBox> structures { get; set; } = new List<System.Windows.Forms.PictureBox>();
private System.Windows.Forms.PictureBox structure;
private string name;

Related

move Form2 according to form1

My problem is:
i want Form 2 to be moved only when I move form 1, and it will always stay beneath Form1.
i tried everything i could think of: Location point and set desktop position, i tried a timer of realtime moving , i just cant get it , this shouldn't be so difficult :(
i'm using a panel to move form 1
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
mov = 1;
movX = e.X;
movY = e.Y;
}
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
if (mov == 1)
{
this.SetDesktopLocation(MousePosition.X - movX, MousePosition.Y - movY);
}
}
private void panel1_MouseUp(object sender, MouseEventArgs e)
{
mov = 0;
}
i also tried to make One form and put panels in it and make the form transparent, but i get an issue when i'm trying to move the form via the panel.
i found solution on this:
Move Form1 when I move Form2 in C#
in first form:
protected override void OnLocationChanged(EventArgs e)
{
if (secondForm == null)
{
secondForm = new SecondForm();
}
if (secondForm.wasShown == true)
{
secondForm.Location = new Point(this.Left - parentOffset.X,
this.Top - parentOffset.Y);
}
base.OnLocationChanged(e);
}
in the second form:
public bool wasShown = false;
private void SecondForm_Load(object sender, EventArgs e)
{
this.StartPosition = FormStartPosition.Manual;
Location = new Point(topForm.lX -40, topForm.lY +85);
wasShown = true;
this.Owner = topForm;
}

Referencing multiple instantiated pictureboxes

I'm very new to C# but trying to learn so bear with me if my syntax isn't accurate. I am able to create a picturebox with a button and it appears on screen. I can then move it around the screen just fine with a mouse down / mouse move function. I then hit the button to instantiate another picturebox to be created and can move that one around as well, but when I try to move the first picturebox the second one moves instead and goes insane. Is there a way to reference or tag the boxes on instantiation so that when I click on any of them I can move them around the screen?
public partial class Form1 : Form
{
Point MP;
private static Control PB;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
int picSizeX = Properties.Resources.police.Width / 3;
int picSizeY = Properties.Resources.police.Height / 3;
PictureBox pb = new PictureBox();
pb.Location = new Point(100, 100);
pb.Size = new Size(picSizeX, picSizeY);
pb.Image = new Bitmap(Properties.Resources.police);
pb.SizeMode = PictureBoxSizeMode.StretchImage;
Controls.Add(pb);
pb.Tag = "veh";
PB = pb;
pb.MouseDown += Pb_MouseDown;
pb.MouseMove += Pb_MouseMove;
pb.MouseHover += Pb_MouseHover;
}
private void Pb_MouseHover(object sender, EventArgs e)
{
PB.MouseHover += PB_MouseHover;
}
private void PB_MouseHover(object sender, EventArgs e)
{
}
private void Pb_MouseDown(object sender, MouseEventArgs e)
{
MP = e.Location;
}
private void Pb_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
PB.Left = e.X + PB.Left - MP.X;
PB.Top = e.Y + PB.Top - MP.Y;
}
}
}
Actually there is no need to have Control at class level.
In the event method there is a parameter called object sender that contains a reference to the control/object that raised the event.
Point MP;
//private Control PB; //commented out as it is not required
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
int picSizeX = Properties.Resources.police.Width / 3;
int picSizeY = Properties.Resources.police.Height / 3;
PictureBox pb = new PictureBox();
pb.Location = new Point(100, 100);
pb.Size = new Size(picSizeX, picSizeY);
pb.Image = new Bitmap(Properties.Resources.police);
pb.SizeMode = PictureBoxSizeMode.StretchImage;
Controls.Add(pb);
pb.Tag = "veh";
//PB = pb;
pb.MouseDown += Pb_MouseDown;
pb.MouseMove += Pb_MouseMove;
pb.MouseHover += Pb_MouseHover;
}
private void Pb_MouseHover(object sender, EventArgs e)
{
Control pbObj = sender as PictureBox; //sender refers to control that raised the event
pbObj.MouseHover += PB_MouseHover;
}
private void PB_MouseHover(object sender, EventArgs e)
{
}
private void Pb_MouseDown(object sender, MouseEventArgs e)
{
MP = e.Location;
}
private void Pb_MouseMove(object sender, MouseEventArgs e)
{
Control pbObj = sender as PictureBox; //sender refers to control that raised the event
if (e.Button == MouseButtons.Left)
{
pbObj.Left = e.X + pbObj.Left - MP.X;
pbObj.Top = e.Y + pbObj.Top - MP.Y;
}
}

How to prevent repeating code using events

I am a beginner programmer and I feel like I am repeating code unnecessarily. I want to make a picture puzzle game consisting of 16 pictureboxes. The problem is that I feel like I have to repeat code for each picturebox's events as in the below example:
Point move;
bool isDragging = false;
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
isDragging = true;
move = e.Location;
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if(isDragging == true)
{
pictureBox1.Left += e.X - move.X;
pictureBox1.Top += e.Y - move.Y;
pictureBox1.BringToFront();
}
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
isDragging = false;
}
Just create one method for each of your 3 events:
private void pictureBox_MouseDown(object sender, MouseEventArgs e)
{
isDragging = true;
move = e.Location;
}
private void pictureBox_MouseMove(object sender, MouseEventArgs e)
{
if(isDragging == true)
{
// Luckily the sender parameter will tell us which PictureBox we are dealing with
PictureBox pb = (PictureBox)sender;
pb.Left += e.X - move.X;
pb.Top += e.Y - move.Y;
pb.BringToFront();
}
}
private void pictureBox_MouseUp(object sender, MouseEventArgs e)
{
isDragging = false;
}
Then go to each of your 16 picture boxes in the designer and set the MouseUp event handler to point to pictureBox_MouseUp and the MouseMove event handler to point to pictureBox_MouseMove and the MouseDown event handler to point to pictureBox_MouseMove. Do this for each of the 16 picture boxes.
Try to trigger same events for all PictureBox Controls
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
isDragging = true;
move = e.Location;
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
PictureBox pictureBox = sender as PictureBox;
if(isDragging == true)
{
pictureBox .Left += e.X - move.X;
pictureBox .Top += e.Y - move.Y;
pictureBox .BringToFront();
}
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
isDragging = false;
}
Create a new component contained Image component and set dock parent container. Write your drag drop codes into the new component.
For example,
public partial class DraggablePictureBox : UserControl
{
public DraggablePictureBox()
{
InitializeComponent();
}
/// <summary>
/// Sets image of inner picture
/// </summary>
public Image Image
{
get {
return InnerPictureBox.Image;
}
set
{
InnerPictureBox.Image = value;
}
}
private void InnerPictureBox_MouseMove(object sender, MouseEventArgs e)
{
if (isDragging == true)
{
this.Left += e.X - move.X;
this.Top += e.Y - move.Y;
this.BringToFront();
}
}
private void InnerPictureBox_MouseUp(object sender, MouseEventArgs e)
{
isDragging = false;
}
private void InnerPictureBox_MouseDown(object sender, MouseEventArgs e)
{
isDragging = true;
move = e.Location;
}
private Point move;
private bool isDragging = false;
}
Now you have a one drag drop code for images.
One way to combat this would be to put these in methods, for example
MovePicturePox(Point move, Point newPos, PictureBox pb)
{
pb.Left += newPos.X - move.X;
pb.Top += newPos.Y - move.Y;
pb.BringToFront();
}
These methods can then be called like so
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if(isDragging == true)
{
MovePictureBox(move, new Point(e.X, y.Y), pictureBox1);
}
}

Drag and Drop something

I made a class Schalter (eng. switch) and now I want to drag and drop this to an other position. The Schalter is a just an object with 0 or 1 as output and it has some drawing in it. I tried something but it just worked half. When I move it it moves much too fast.
Here the code I tried:
namespace Schaltungszeichner {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
s = new Schalter(this);
this.DoubleBuffered = true;
}
private bool myMouseDown = false;
private int myMouseX, myMouseY;
Schalter s;
private void Form1_Paint(object sender, PaintEventArgs e) {
s.zeichnen(e.Graphics);
}
private void Form1_MouseMove(object sender, MouseEventArgs e) {
if (myMouseDown) {
s.X += e.X - myMouseX;
s.Y += e.Y - myMouseY;
}
}
private void Form1_MouseUp(object sender, MouseEventArgs e) {
myMouseDown = false;
}
private void Form1_MouseDown(object sender, MouseEventArgs e) {
if (s.isClicked(e.X, e.Y)) {
s.Out = !s.Out;
myMouseDown = true;
myMouseX = e.X;
myMouseY = e.Y;
}
}
}
}
The problem is that MouseEventArgs holds the mouse position relative to the object which owns the event and not the object being moved. You need to account for this by subtracting the starting position of the moving object.
In Form1_MouseDown change:
myMouseX = e.X;
myMouseY = e.Y;
to:
myMouseX = e.X - s.X;
myMouseY = e.Y - s.Y;
And in Form1_MouseMove change:
s.X += e.X - myMouseX;
s.Y += e.Y - myMouseY;
to:
s.X = e.X - myMouseX;
s.Y = e.Y - myMouseY;
I would also consider renaming myMouseX and myMouseY to something that reflects the values that they now hold, like differenceX and differenceY.

image from picturebox1 to picturebox2

I made a script for 1 form with 2 pictureboxes, until here everything is fine.
If you execute the code below, than you can see you can move the picturebox1 and also drop it inside picturebox2. Now i would like that the dropped picturebox1 can be resized, rotated and moved around inside picturebox2 (once executed by client).
I have looked around but can not find the answers to this problem. Any help i would appreciate, Thank you
Here is the code:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
int x = 0;
int y = 0;
bool drag = false;
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
pictureBox1.DoDragDrop(pictureBox1.Image, DragDropEffects.Copy);
x = e.X;
y = e.Y;
drag = true;
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (drag)
{
//position new get
pictureBox1.Top += e.Y - y;
pictureBox1.Left += e.X - x;
}
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
drag = false;
}
private void pictureBox2_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.All;
}
private void pictureBox2_DragDrop(object sender, DragEventArgs e)
{
pictureBox2.Image = (Image)e.Data.GetData(DataFormats.Bitmap);
}
private void Form1_Load(object sender, EventArgs e)
{
pictureBox2.AllowDrop = true;
}
}
}
In order to resize the pictureboxes you can define the following methods:
private void IncreaseSize(PictureBox p,int dt)
{
Size size = p.Size;
size.Height = size.Height + dt;
size.Width=size.Width + dt;
p.Size = size;
}
private void DecreaseSize(PictureBox p, int dt)
{
Size size = p.Size;
size.Height = size.Height - dt;
size.Width = size.Width - dt;
p.Size = size;
}
These methods can be called to events that you decide in your main form e.g:
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
IncreaseSize(pictureBox1,5);
}
private void pictureBox2_MouseMove(object sender, MouseEventArgs e)
{
DecreaseSize(pictureBox2, 10);
}

Categories