How to draw images in a click event? - c#

So I am just experimenting with drawing images and other things, however it seems that my code only works in the load form event?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Interface_Editing_Test
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//This works perfectly
/*Image i = Image.FromFile(#"C:\Users\Simon\Pictures\clickedbutton.jpg");
Bitmap b = (Bitmap)panel1.BackgroundImage;
using (Graphics g = Graphics.FromImage(b))
{
g.DrawImage(i, 0, 0, i.Size.Width, i.Size.Height);
}*/
}
private void panel1_Click(object sender, EventArgs e)
{
//Doesnt draw anything, but will show the message box
Image i = Image.FromFile(#"C:\Users\Simon\Pictures\clickedbutton.jpg");
Bitmap b = (Bitmap)panel1.BackgroundImage;
using (Graphics g = Graphics.FromImage(b))
{
//MessageBox.Show(" ");
g.DrawImage(i, 0, 0, i.Size.Width, i.Size.Height);
}
}
}
}
I know it is most likely something simple that I am overlooking but I would appreciate if someone could give me some insight in to whats happening. Thanks

Windows doesn't know that you changed the image. The Image class doesn't have any events that anybody could listen to so it knows that the image was changed. It works in the Load event because the window isn't visible yet, it will get painted right after that. So you can see the changed image. It doesn't work in the Click event handler since the panel is already displayed and has no reason to repaint itself.
Simply let it know that repainting is required. Add this line of code to the bottom of the method:
panel1.Invalidate();

It seems that this is probl;em related to handling click event inside a panel due to different controls inside it.
Make sure that your application handles panel1_click event. (May be through debugger you will come to know it).
Application may not handle this event due to different reasons such as different controls presence on panels,etc.
You can refer Following question having the same issue as you:
Panel events won't work in c#
Handling a click event anywhere inside a panel in C#
This working example might guid you:
private Bitmap _bmp = new Bitmap(250, 250);
public Form1()
{
InitializeComponent();
panel1.Click += new MouseEventHandler(panel1_Click);
panel1.Paint += new PaintEventHandler(panel1_Paint);
using (Graphics g = Graphics.FromImage(_bmp))
g.Clear(SystemColors.Window);
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawImage(_bmp, new Point(0, 0));
}
private void panel1_Click(object sender, MouseEventArgs e)
{
using (Graphics g = Graphics.FromImage(_bmp))
{
g.DrawString("Mouse Clicked Here!", panel1.Font, Brushes.Black, e.Location);
}
panel1.Invalidate();
}

Related

Make Button Follow Mouse Cursor

I'm trying to make a button follow the cursor, but my code only seems to just go to the mouse cursor right after execution and just stay there. Can anyone give me the correct code and help me?
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 WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
button1.Location = Cursor.Position;
}
}
}
I would suggest overriding the OnMouseMove method of the MainForm and using the Location property of the MouseEventArgs e argument. This will provide the correct Client coordinates of the cursor taking into account where MainForm is located on the screen. Then you can offset that value using the Width and Height properties of buttonMoveMe to center it on the mouse.
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
var point = new Point(
e.Location.X - (buttonMoveMe.Width / 2),
e.Location.Y - (buttonMoveMe.Height / 2));
buttonMoveMe.Location = point;
}
}
Be aware that this event _will not be received when the mouse is over the button itself. The button will be getting the MouseMove events (not the MainForm) in this case. In other words, this basic suggestion only moves the button when the mouse leaves the button.
I think you need to use the MouseMove event.
So these are things you need to do:
Create a button control which is going to follow the cursor. (I will call it yourButton)
Open event menu of the control (click on it in the constructor).
Find event MouseMove inside Mouse category.
Double click on it. (This will automatically create the method which will be linked to the event)
In this method write: yourButton.Location = e.Location;
So it should look like that:
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
yourButton.Location = e.Location;
}
In my example I made button follow my cursor inside the form.
If you need shorter way, you can just copy-paste the method I wrote before and in the form class constructor add:
this.MouseMove += Form1_MouseMove;
In this way your code would look like that:
public Form1()
{
InitializeComponent();
this.MouseMove += Form1_MouseMove;
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
yourButton.Location = e.Location;
}
Hope this will help you, have a nice day!
UPD:
In case you want the cursor to be in the center of the button, you should edit our previous Form1_MouseMove and add one more event.
Edit the code of Form1_MouseMove, now it should be:
yourButton.Location = new Point(e.X - yourButton.Width / 2, e.Y - yourButton.Height / 2);
Now you need to use MouseMove method of the button (Follow the previous steps, but for button (Click on it -> Events -> Mouse category -> double click on MouseMove))
In newly created method write:
yourButton.Location = new Point(e.X + yourButton.Left - yourButton.Width / 2, e.Y + yourButton.Top - yourButton.Height / 2);
Hope this helped now)
Your Form1_Load method is only executed, as its name says, when the form is loaded.
You want to execute your code every time the mouse move, si you can do it like this (not tested):
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.MouseMove += Form1_MouseMove;
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
button1.Location = Cursor.Position;
}
}

C# windows form, Line wont Draw! canvas is not defined

What is needed to define 'canvas' on line 27? I've looked everywhere but it only gives respoenses of why an object might not be defined, and not about why the specific object canvas is not defined. Can someone tell me what i'm Missing?
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 WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void canvas_Paint(object sender, PaintEventArgs e)
{
Graphics gObject = canvas.CreateGraphics();
Brush red = new SolidBrush(Color.Red);
Pen redPen = new Pen(red, 8);
gObject.DrawLine(redPen, 10, 10, 35, 500);
}
}
}
That canvas must be a control in the form. You got to add it in the designer and give it the canvas name. What kind? Hmm… I'd say use a PictureBox.
You would also need to link the Paint event to canvas_Paint from the properties panel (events tab). And yes, e.Graphics is preferred over using CreateGraphics.
Where did you get that code from?

c# winforms creating pictureboxes dynamically at runtime doesn't work

I'm trying to create PictureBoxes dynamically at runtime with c# winforms.
My project: I want to write a program, which has a node-GUI (a GUI with various types of nodes, some kind of boxes, which are connected together and process an image, an audio stream or whatever).
Therefor i want to create and delete Pictureboxes dynamically at runtime, but my testing won't work, the form is empty.
Here is my code:
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 AudioNodeGUI
{
public partial class AudioNodeWindow : Form
{
public AudioNodeWindow()
{
InitializeComponent();
}
private void AudioNodeWindow_Load(object sender, EventArgs e)
{
}
private void AudioNodeWindow_Paint(object sender, PaintEventArgs e)
{
PictureBox start_picture = new PictureBox
{
Name = "pictureBox",
Size = new Size(19, 32),
Location = new Point(100, 100),
Visible = true,
Image = Bitmap.FromFile(#"C:\Users\Benjamin.MBENJAMIN\Pictures\Start.png"),
};
start_picture.Show();
}
}
}
Please help !
You need to add the control you created to the Forms control.
Before you Show() the picturebox, try adding this line:
Controls.Add(start_picture);
Secondly, you don't want to doing this onPaint()!
I would say you need to move it to Load() method instead, that way it will be done when the form loads, rather than everytime it's repainted!
Change:
start_picture.Show();
to:
this.Controls.Add(start_picture);
start_picture.Show();
Controls.Add tells the form that the PictureBox is meant to be part of this specific form.
Also, you will not want to do this in in your Paint event handler. Leaving it there will result in many more picture boxes than you would like I expect...
I have change your code as :
PictureBox start_picture = new PictureBox
{
Name = "pictureBox",
Size = new Size(19, 32),
Location = new Point(100, 100),
Visible = true,
Image = Bitmap.FromFile(#"D:\test\learn.png"),
};
//start_picture.Show();
Controls.Add(start_picture);

mousewheel event not triggered after clicking off the canvas

thanks to http://www.eqqon.com/index.php/Piccolo_Snippets, i had mousewheel zooming working well until i added winform widgets to the form outside of the canvas; see pic of a test form below:
i found that if i clicked on button1, and moused back onto the canvas, i no longer get mousewheel events. Other mouse events (e.g. PNode entry/leave) still work however. even after clicking on the canvas, the mousewheel is still dead. the canvas's mousedown event works fine also. so only the mousewheel breaks. below is minimalist code to demonstrate what i'm seeing.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using UMD.HCIL.Piccolo;
using UMD.HCIL.Piccolo.Event;
using UMD.HCIL.Piccolo.Nodes;
namespace piccolo_wheel_test {
public partial class Form1 : Form {
int mdown_count = 0;
int mwheel_count = 0;
public Form1() {
InitializeComponent();
PNode rect = PPath.CreateRectangle(40, 40, 20, 50);
rect.Brush = Brushes.Blue;
pCanvas1.Layer.AddChild(rect);
pCanvas1.Camera.MouseWheel += new PInputEventHandler(Camera_MouseWheel);
pCanvas1.Camera.MouseDown += new PInputEventHandler(Camera_MouseDown);
}
void Camera_MouseWheel(object sender, PInputEventArgs e) {
Debug.WriteLine("got mouse wheel: " + (mwheel_count++).ToString());
}
void Camera_MouseDown(object sender, PInputEventArgs e) {
Debug.WriteLine("got mouse down: " + (mdown_count++).ToString());
}
private void pCanvas1_Enter(object sender, EventArgs e) {
Debug.WriteLine("enter pcanvas");
}
private void pCanvas1_Leave(object sender, EventArgs e) {
Debug.WriteLine("leave pcanvas");
}
private void button1_Enter(object sender, EventArgs e) {
Debug.WriteLine("enter button");
}
private void button1_Leave(object sender, EventArgs e) {
Debug.WriteLine("leave button");
}
}
}
as an aside, i see that the canvas does not raise "enter"/"leave" events consistently; i see one "enter" when the form loads and one "leave" if i click button1 but no more "enter"/"leave" if i go back and forth. further, when i click on button1, i raises its "enter" event but when i click back on the canvas, "button1" doesn't raise its "leave" event (which it does if i clicked on other winform widgets, such as the trackbar.) thanks.

User Placed Text on a picturebox in c#

I am trying to make a tool that allows me to choose a certain location on a picturebox to put text from a textbox on. It will need to be able to place multiple different texts on the picturebox and then be able to be deleted. This is my current code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace TextboxTool
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
pictureBox1.Image = new Bitmap(pictureBox1.Width, pictureBox1.Height);
}
private void textBox1_MouseClick(object sender, MouseEventArgs e)
{
textBox1.Text = "";
}
private void button1_Click(object sender, EventArgs e)
{
textBox1.Visible = true;
}
private void pictureBox1_Click(object sender, EventArgs e)
{
Graphics G = Graphics.FromImage(pictureBox1.Image);
G.DrawString(textBox1.Text, new Font("Tahoma", 40), Brushes.Black, new Point(MousePosition.X, MousePosition.Y));
}
}
}
At the moment i can type the text in the textbox, but can't draw the string on the picturebox and choose its location. I have a button which is meant to confirm the text written is right and then allow the user to choose its location. Please can someone help me sort this code out?
Thanks-
The MousePosition property is relative to the screen, not the PictureBox.
You should handle the MouseClick event and draw the string at e.X and e.Y.
Alternatively, you can call pictureBox1.PointToClient to transform screen coordinates to control-relative coordinates.
Also, you should dispose the Graphics object in a using statement.
Finally, I'm pretty sure you'll need to call pictureBox1.Invalidate() after modifying the image to force it to repaint.

Categories

Resources