How to remove a created image in C#? - c#

I have it so the user can click on an image view and drag the item elsewhere on the form, doing this creates a new image whilst the original image box stays put. How would I delete one of the duplicated images on click?
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.AllowDrop = true;
this.pictureBox1.MouseDown += pictureBox1_MouseDown;
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
var dragImage = (Bitmap)pictureBox1.Image;
IntPtr icon = dragImage.GetHicon();
Cursor.Current = new Cursor(icon);
DoDragDrop(pictureBox1.Image, DragDropEffects.Copy);
DestroyIcon(icon);
}
}
protected override void OnGiveFeedback(GiveFeedbackEventArgs e)
{
e.UseDefaultCursors = false;
}
protected override void OnDragEnter(DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(Bitmap))) e.Effect = DragDropEffects.Copy;
}
protected override void OnDragDrop(DragEventArgs e)
{
var bmp = (Bitmap)e.Data.GetData(typeof(Bitmap));
var pb = new PictureBox();
pb.Image = (Bitmap)e.Data.GetData(typeof(Bitmap));
pb.Size = pb.Image.Size;
pb.Location = this.PointToClient(new Point(e.X - pb.Width / 2, e.Y - pb.Height / 2));
this.Controls.Add(pb);
}
[System.Runtime.InteropServices.DllImport("user32.dll")]
extern static bool DestroyIcon(IntPtr handle);
}

Just add the delete operation after the drag drop.
protected override void OnDragDrop(DragEventArgs e) {
var pb = new PictureBox {
Image = (Bitmap)e.Data.GetData(typeof(Bitmap))
};
pb.Size = pb.Image.Size;
pb.Location = PointToClient(new Point(e.X - pb.Width / 2, e.Y - pb.Height / 2));
Controls.Add(pb);
// deletion here: Controls.Remove(pictureBox1 or pb);
base.OnDragDrop(e);
}
If you wish to delete it somewhere else, you will need to declare a variable at class level, and assign it with 'pb'. Then you will can decide which one to delete given both pictureBox1 and pb.

Related

How to at runtime allow a user to create a new Picturebox Visual Studio C# Windows Forms Apps

I am trying to create a Form in Visual Studio Windows Forms Apps C# in which during runtime the user or operator can create a new picturebox with a left mouse click and then have the ability to move each picturebox created.
I really do not know where to begin. Anyone have any ideas?
To add a new PictureBox dynamically, you can subscribe to the event Form_MouseClick and create the PictureBox like this:
public Form1()
{
InitializeComponent();
this.MouseClick += Form_MouseClick;
}
private void Form_MouseClick(object sender, MouseEventArgs e)
{
PictureBox pictureBox = new PictureBox();
// cursor location
pictureBox.Location = new Point(e.X, e.Y);
pictureBox.BackColor = Color.Red;
this.Controls.Add(pictureBox);
}
To drag and move the PictureBox, you also nee to subscribe to the event MouseDown, MouseUp, and MouseMove.
Here is a simple demo you can refer to.
private void Form_MouseClick(object sender, MouseEventArgs e)
{
// create new control
PictureBox pictureBox = new PictureBox();
pictureBox.Location = new Point(e.X, e.Y);
pictureBox.BackColor = Color.Red;
this.Controls.Add(pictureBox);
// bind event for each PictureBox
pictureBox.MouseDown += pictureBox_MouseDown;
pictureBox.MouseUp += pictureBox_MouseUp;
pictureBox.MouseMove += pictureBox_MouseMove;
}
Point mouseDownPoint = Point.Empty;
Rectangle rect = Rectangle.Empty;
bool isDrag = false;
private void pictureBox_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
mouseDownPoint = e.Location;
rect = (sender as PictureBox).Bounds;
}
}
private void pictureBox_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (isDrag)
{
isDrag = false;
(sender as PictureBox).Location = rect.Location;
this.Refresh();
}
reset();
}
}
private void pictureBox_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
isDrag = true;
rect.Location = this.PointToClient((sender as PictureBox).PointToScreen(new Point(e.Location.X - mouseDownPoint.X, e.Location.Y - mouseDownPoint.Y)));
this.Refresh();
}
}
private void reset()
{
mouseDownPoint = Point.Empty;
rect = Rectangle.Empty;
isDrag = false;
}
You can add the form elements during runtime:
var picture = new PictureBox
{
Name = "pictureBox",
Size = new Size(16, 16),
Location = new Point(100, 100),
Image = Image.FromFile("test.jpg"),
};
this.Controls.Add(picture);
Afterward, you can move it with the Mouse Events

how to drag and drop label to a new location and set that location as new location of the label using c# in windows form

Using my code I can drag and drop to new location, but when I close my windows form then the location is again reset to the old location. I want the label at its new position after drag and drop even is I close my form or stop debugging(stop execution)
Name of label: label1
CODE:
namespace EINS_FloorMap
{
public partial class EINS_FloorMap : Form
{
clsConnection_DAL objCore = new clsConnection_DAL(true, true);
private System.Drawing.Point StartPoint;
private bool IsMouseDown = false;
public EINS_FloorMap()
{
InitializeComponent();
}
private void label1_MouseDown_1(object sender,
System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
IsMouseDown = true;
label1.BringToFront();
StartPoint = e.Location;
}
}
private void label1_MouseUp_1(object sender, System.Windows.Forms.MouseEventArgs e)
{
IsMouseDown = false;
this.label1.Location = new System.Drawing.Point(
this.label1.Location.X,this.label1.Location.Y
);
}
private void label1_MouseMove_1(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (IsMouseDown)
{
label1.Left = e.X + label1.Left - StartPoint.X;
label1.Top = e.Y + label1.Top - StartPoint.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);
}

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;
}
}

C# Winform - Smiley box like messenger [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I want to make i smiley box like live messenger.
How can i do that? I want to get the selected picture?
Thanks?
I would use a ToolStrip and a ToolStripSplitButton control and then I'd create my own control inhrited form a panel to show the smiles contained in a picturebox when will happen the click on the ToolStripSplitButton.
I tried to simulate the behaviour you would like to do. So here is some code:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.SuspendLayout();
List<Bitmap> Smiles = new List<Bitmap>(); //Add images
ToolStripSplitButton _toolStripSplitButton = new ToolStripSplitButton();
_toolStripSplitButton.Size = new Size(23, 23);
//_toolStripSplitButton.Image = myImage; //Add the image of the stripSplitButton
ToolStrip _toolStrip = new ToolStrip();
_toolStrip.Size = new Size(ClientSize.Width, 10);
_toolStrip.Location = new Point(0, this.ClientSize.Height - _toolStrip.Height);
_toolStrip.BackColor = Color.LightGray;
_toolStrip.Dock = DockStyle.Bottom;
_toolStrip.Items.AddRange(new ToolStripItem[] { _toolStripSplitButton });
SmileBox smilebox = new SmileBox(new Point(_toolStripSplitButton.Bounds.Location.X, _toolStrip.Location.Y - 18), 6);
smilebox.Visible = false;
Controls.Add(smilebox);
foreach (Bitmap bmp in Smiles)
smilebox.AddItem(bmp);
_toolStripSplitButton.Click += new EventHandler(delegate(object sender, EventArgs e)
{
smilebox.Visible = true;
});
Click += new EventHandler(delegate(object sender, EventArgs e)
{
smilebox.Visible = false;
});
this.Controls.Add(_toolStrip);
this.ResumeLayout();
}
void Form1_Click(object sender, EventArgs e)
{
throw new NotImplementedException();
}
}
class SmileBox : Panel
{
public List<Item> Items
{
get;
set;
}
Size _ItemSpace = new Size(20, 20);
Point _ItemLocation;
int _rowelements = 0;
public SmileBox(Point Location, int RowElements)
{
BackColor = Color.LightGray;
Height = _ItemSpace.Height;
Width = _ItemSpace.Width * RowElements;
this.Location = new Point(Location.X, Location.Y - Height);
_ItemLocation = new Point(0, 0);
_rowelements = RowElements;
}
int count = 1;
public void AddItem(Bitmap Image)
{
Item item = new Item(_ItemSpace, _ItemLocation, Image);
if (_ItemLocation.X + _ItemSpace.Width >= Width)
_ItemLocation = new Point(0, _ItemLocation.Y);
else
_ItemLocation = new Point(_ItemLocation.X + _ItemSpace.Width, _ItemLocation.Y);
if (count == _rowelements)
{
_ItemLocation = new Point(_ItemLocation.X, _ItemLocation.Y + _ItemSpace.Height);
Height += _ItemSpace.Height;
Location = new Point(Location.X, Location.Y - _ItemSpace.Height);
count = 0;
}
count++;
Controls.Add(item);
}
}
class Item : PictureBox
{
int _BorderSpace = 2;
public Item(Size Size, Point Location, Bitmap Image)
{
this.Size = new Size(Size.Width - 2 * _BorderSpace, Size.Height - 2 * _BorderSpace);
this.Location = new Point(Location.X + _BorderSpace, Location.Y + _BorderSpace);
this.Image = new Bitmap(Image, this.ClientSize);
Click += new EventHandler(delegate(object sender, EventArgs e)
{
//Here what do you want to do when the user click on the smile
});
MouseEnter += new EventHandler(delegate(object sender, EventArgs e)
{
Focus();
Invalidate();
});
}
protected override void OnMouseDown(MouseEventArgs e)
{
this.Focus();
base.OnMouseDown(e);
}
protected override void OnEnter(EventArgs e)
{
this.Invalidate();
base.OnEnter(e);
}
protected override void OnLeave(EventArgs e)
{
this.Invalidate();
base.OnLeave(e);
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
if (this.Focused)
{
ClientRectangle.Inflate(-1, -1);
Rectangle rect = ClientRectangle;
ControlPaint.DrawFocusRectangle(pe.Graphics, rect);
}
}
}
Here is a snapshot of what create this code:
And when you are over a smile:
And here you can click on single item.
Create a user control or a new form (if you want a floating thing), with picture boxes for each smilies. Whenever a user clicks on a picture box (Click event) you can register the click and paste the smiley to the appropriate location.
Actually, you can create a new picture box class that inherits everything from the built-in one, and you add one public string, which contains the smiley's code. You get the sender object in the event, so all you have to do is to read that string in the Click event's function.

Categories

Resources