C# - Drag and Drop & Keep Control - c#

So I am trying to make a drag and drop application that drags something on a panel. I did it before and I have forgot the code that I used for it. I would also like it to have an event too. Here is an example that failed to work:
private void pictureBox1_Click(object sender, EventArgs e)
{
PictureBox flower1 = new PictureBox();
flower1.Image = pictureBox1.Image;
flower1.Location = new Point(panel1.Location.X, panel1.Location.Y);
flower1.Width = 100;
this.Controls.Add(flower1);
flower1.MouseDown += new MouseEventHandler(flower1_MouseDown);
}
void flower1_MouseDown(object sender, MouseEventArgs e)
{
//flower1.Location = new Point(MousePosition.X, MousePosition.Y);
}
I wanted me to click on a flower, then it would be placed onto the panel then, if the mouse is clicked over that control duplicated onto the panel, then make the location the mouse cursors location. How would I go about doing any of this? It does not even appear to duplicate.
EDIT: Just realised that the image is underneath the panel making it not able to be seen. That's one issue, now how do I get it to drag and drop?

private void pictureBox1_Click(object sender, EventArgs e)
{
PictureBox flower1 = new PictureBox();
flower1.Image = pictureBox1.Image;
flower1.Location = Point.Empty;
flower1.Width = 100;
flower1.Parent = panel1;
flower1.MouseDown += new MouseEventHandler(flower1_MouseDown);
}

Related

MouseLeave detection not working with ImageForm

I've got a smaller image in my form. When the user hovers over the image it brings up a larger view of the image (that follows the mouse, but stays a certain distance from the mouse). In order to do this I am generating a Form with no FormBorderStyles when the cursor hovers the image.
The problem I'm running into is that the first form doesn't seem to detect any longer that the mouse is hovering or leaving the PictureBox once the form activates. The Form also doesn't follow the cursor.
Here is the slimmed down version of what I've got:
C#
bool formOpen = false;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
pictureBox1.MouseHover += pictureBox1_MouseHover;
pictureBox1.MouseLeave +=pictureBox1_MouseLeave;
}
void pictureBox1_MouseHover(object sender, EventArgs e)
{
if (formOpen == false)
{
Form form = new Form();
form.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
form.BackColor = Color.Orchid;
//Show the form
form.Show();
form.Name = "imageForm";
this.AddOwnedForm(form);
//Set event handler for when the mouse leaves the image area.
//form.MouseLeave += form_MouseLeave;
//Set the location of the form and size
form.BackColor = Color.Black;
form.Dock = DockStyle.Fill;
form.Size = new Size(30, 30);
form.BackgroundImageLayout = ImageLayout.Center;
this.TopMost = true;
formOpen = true;
form.Location = new Point(Cursor.Position.X, Cursor.Position.Y);
}
}
private void pictureBox1_MouseLeave(object sender, EventArgs e)
{
//MessageBox.Show("Worked");
}
}
The MouseLeave (and other events) was not recognized because the opening of the popup window and especially making it topmost=true took away the focus from the original form and its PictureBox.
It also didn't move because not code for moving was provided..
Here are a few changes that will make the form move:
You need a reference to it at the form1 level
you need to move it in the MouseMove event
Note that Hover is a once-only type of event. It fires only once until you leave the control.. (Note: Setsu has switched from Hover to Enter. This works fine, but lacks the short delay before showing the 2nd Form. If you want that back you can either switch back to Hover or you can fake the hover delay by a Timer, which is what I often do.)
// class level variable
Form form;
private void Form1_Load(object sender, EventArgs e)
{
pictureBox1.MouseEnter += pictureBox1_MouseEnter;
pictureBox1.MouseLeave +=pictureBox1_MouseLeave;
pictureBox1.MouseMove += pictureBox1_MouseMove; // here we move the form..
}
// .. with a little offset. The exact numbers depend on the cursor shape
void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if ((form != null) && form.Visible)
{
form.Location = new Point(Cursor.Position.X + 5, Cursor.Position.Y + 5);
}
}
void pictureBox1_MouseEnter(object sender, EventArgs e)
{
// we create it only once. Could also be done at startup!
if (form == null)
{
form = new Form();
form.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
//form.BackColor = Color.Orchid;
form.Name = "imageForm";
this.AddOwnedForm(form);
form.BackColor = Color.Black;
form.Dock = DockStyle.Fill;
form.Size = new Size(30, 30);
form.BackgroundImageLayout = ImageLayout.Center;
//this.TopMost = true; // wrong! this will steal the focus!!
form.ShowInTaskbar = false;
}
// later we only show and update it..
form.Show();
form.Location = new Point(Cursor.Position.X + 5, Cursor.Position.Y + 5);
// we want the Focus to be on the main form!
Focus();
}
private void pictureBox1_MouseLeave(object sender, EventArgs e)
{
if (form!= null) form.Hide();
}
MouseHover = Occurs when the mouse pointer rests on the control. (msdn)
Try MouseMove instead.

Picturebox change location on mouseenter without white borders appearing

Hello I'm trying to do the effect that the button is pressed, so when mousenter moving 2px the picturebox, I'm using picturebox as button because It allows me to set transparent backgrounds.
I tried forcing the background to transparent in various events(paint,pevious change location,after change location),but without success.
I think that is caused for the re-drawing when changing an element, because the white part of the background that whas "hidden" by the picturebox appears.
Any idea how to solve that?
Thanks in advance
private void buttonX2_MouseLeave(object sender, EventArgs e)
{
((PictureBox) sender).Location = new Point(
((PictureBox) sender).Location.X, ((PictureBox) sender).Location.Y - 2);
}
private void buttonX2_MouseEnter(object sender, EventArgs e)
{
((PictureBox)sender).Location = new Point(
((PictureBox)sender).Location.X, ((PictureBox)sender).Location.Y + 2);
}
The problem seems to come from moving in or out too slowly. If you do that you will say enter from below, but the PB is moving up so you're out of it again, so it moves down and therefore you're in it again etc..The correct repainting of the Background can't keep up with these 'Jittering ButtBoxes'..
First, as Hans noted, make things less obtrusive: make the Form's BackColor dark, maybe even black!
Second to avoid the problem of jittering, move the Mouse Cursor itself a few pixels with the Pictureboxes, like this:
private void pictureBox1_MouseEnter(object sender, EventArgs e)
{
PictureBox PB = (PictureBox)sender;
Point MP = Cursor.Position;
this.SuspendLayout();
PB.Location = new Point( PB.Location.X, PB.Location.Y - 2);
Cursor.Position = new Point(MP.X, MP.Y - 2);
this.ResumeLayout();
}
private void pictureBox1_MouseLeave(object sender, EventArgs e)
{
PictureBox PB = (PictureBox)sender;
Point MP = Cursor.Position;
this.SuspendLayout();
PB.Location = new Point( PB.Location.X, PB.Location.Y + 2);
Cursor.Position = new Point(MP.X, MP.Y + 2);
this.ResumeLayout();
}

How to retain existing images in a panel while redrawing in c#?

I have a panel where I am drawing images on button click. But on the second button click, the previously drawn image is being replaced by the new Image.
void panel_Image_Paint(object sender, PaintEventArgs e)
{
if (Clipboard.ContainsImage())
{
Point p1 = new Point(i, 0);
e.Graphics.DrawImage(Clipboard.GetImage(), p1);
i += img.Width;
}
}
I want to retain the previously drawn image in the panel, when the new image is being drawn. The clipboard is being refreshed on each button click with the new image. Any help would be highly appreciated!!!!
Thanks..
I'm not sure how the paint event actually works and what causes your images to disappear , but what you can try is adding your images to a list and then looping through the list to get all of your images displayed on the panel.
Try this code:
int i = 0;
List<Image> Images = new List<Image>();
private void panel1_Paint(object sender, PaintEventArgs e)
{
if (Clipboard.ContainsImage())
{
Images.Add(Clipboard.GetImage());
foreach (Image item in Images)
{
e.Graphics.DrawImage(item, new Point(i,0));
i += Clipboard.GetImage().Width;
}
}
i = 0;
}
Don't forget to call the Invalidate function.
private void button1_Click(object sender, EventArgs e)
{
panel1.Invalidate();
}

Relocate image on mouseover

I am trying to recreate a mac style menu bar is c# on visual studio 2012. I can get the image to move on mouseEnter and relocate back to the original place on mouseLeave. I do this by setting the location of the picturebox.
The problem I have is when I mouseEnter the image if I leave the mouse in the area at the bottom of the image between the bottom of the old image location and the bottom of the new image location the image will jump constantly between the two location.
Can anyone advise how to stop this or avoid it.
private void pic1_MouseEnter(object sender, EventArgs e)
{
pic1.Location = new Point(328, 300);
}
private void pic1_MouseLeave(object sender, EventArgs e)
{
pic1.Location = new Point(328, 316);
}
Try to detach event handler before moving image location, then attach it back after. Something like this :
private void pic1_MouseEnter(object sender, EventArgs e)
{
pic1.MouseEnter -= pic1_MouseEnter;
pic1.MouseLeave -= pic1_MouseLeave;
pic1.Location = new Point(328, 300);
pic1.MouseEnter += pic1_MouseEnter;
pic1.MouseLeave += pic1_MouseLeave;
}
True, since moving the image triggers the MouseLeave event, Leave callback sends it to its original location, thus triggering MouseEnter and so on for ever and ever (unless you move the mouse away).
I would suggest you eliminate MouseLeave callback and keep a state of where the image is:
private bool retracted = false;
private void pic1_MouseEnter(object sender, EventArgs e)
{
if (retracted)
{
pic1.Location = new Point(328, 316);
}
else
{
pic1.Location = new Point(328, 300);
}
retracted = !retracted;
}
Thanks for all the solutions but none had the desired effect but I have come up with a solution using mouseHover and mouseLeave. On hover moves the image to the desired location ad the leave returns it to the original spot.
private void pic1_MouseLeave(object sender, EventArgs e)
{
pic1.Location = new Point(328, 316);
}
private void pic1_MouseHover(object sender, EventArgs e)
{
pic1.Location = new Point(328, 310);
}

Moving a control within another control's visible area

I have a PictureBox that is inside a TabPage, and of course this TabPage is part of a TabView and this TabView is inside a Form. I want users be able to move this picture box within the tab page. For this I am using the MouseDown, MouseMove and MouseUp events of the picture box:
private void pictureBoxPackageView_MouseDown(object sender, MouseEventArgs e)
{
if (!_mapPackageIsMoving)
{
_mapPackageIsMoving = true;
}
}
private void pictureBoxPackageView_MouseMove(object sender, MouseEventArgs e)
{
if(_mapPackageIsMoving)
{
pictureBoxPackageView.Location = MousePosition; //This is not exact at all!
return;
}
//Some other code for some other stuff when picturebox is not moving...
}
private void pictureBoxPackageView_MouseUp(object sender, MouseEventArgs e)
{
if (_mapPackageIsMoving)
{
_mapPackageIsMoving = false; //Mouse button is up, end moving!
return;
}
}
But my problem lies in the MouseMove event. As soon as I move mouse after button down, the picture box jumps out of tab page's visible area.
I need to know how to handle the move only within the rectangle of the tab page, and if picture box is being dragged out of tab view's visible area, it shouldn't move anymore unless user brings the mouse inside the tab view's visible rectangle.
Any helps/tips will be appriciated!
You need a variable to hold the original position of the PictureBox:
Modified from a HansPassant answer:
private Point start = Point.Empty;
void pictureBoxPackageView_MouseUp(object sender, MouseEventArgs e) {
_mapPackageIsMoving = false;
}
void pictureBoxPackageView_MouseMove(object sender, MouseEventArgs e) {
if (_mapPackageIsMoving) {
pictureBoxPackageView.Location = new Point(
pictureBoxPackageView.Left + (e.X - start.X),
pictureBoxPackageView.Top + (e.Y - start.Y));
}
}
void pictureBoxPackageView_MouseDown(object sender, MouseEventArgs e) {
start = e.Location;
_mapPackageIsMoving = true;
}

Categories

Resources