I want to draw(Fill) a rectangle in to my form when I click on the button. But I can't manage to make it work and dont know what is wrong.
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics; //verklaart naar object Graphics
Vierkant vierkant = new Vierkant();
}
private void vierkant_Click(object sender, EventArgs e)
{
SolidBrush myBrush = new SolidBrush(Color.Cyan);
g.FillRectangle(myBrush, 20, 20, 50, 50);
}
Shall the drawing persist or not? Meaning: Shall it still be there after eg a Resize or maximize etc? Also: What is a Vierkant?
To make it persist you can use code like this:
private void Form1_Paint(object sender, PaintEventArgs e)
{
if (paintIt)
using( SolidBrush myBrush = new SolidBrush(Color.Cyan) )
e.Graphics.FillRectangle(myBrush, 20, 20, 50, 50);
}
bool paintIt = false;
private void vierkant_Click(object sender, EventArgs e)
{
paintIt = true;
this.Invalidate();
// ?? what is this supposed to do or be??
// Vierkant vierkant = new Vierkant();
}
This will work if both events are hooked up. For more interesting drawings you will need to store more than a bool flag but Lists of a drawAction class you need to invent which will include the shapes, its data, brushes etc..
If you replace paintIt = true; by paintIt = !paintIt; the Rectangle will appear and disappear on each click..
Related
I'm new to c#, coming from a python / wxpython background. I'm still very inexperienced.
I'm trying to create a user workspace that allows objects that have a representative shape (box or circle) to be placed. I'd like the user to be able to pan and zoom within the workspace. Eventually I want to have the items have attributes and be able to be connected together with lines.
I created a simple c# app that allows me to paint squares over a tiled .png grid background, but I can't figure out to set up a real workspace to pan or zoom.
At this stage some high level suggestions would be great.
Here is my code just FYI (be kind)
public partial class MainForm : Form
{
bool global_draw_redbox = false;
public MainForm()
{
InitializeComponent();
}
private void redbox(Point mousepos)
{
System.Drawing.Graphics graphicsObj;
graphicsObj = CreateGraphics();
Pen myPen = new Pen(System.Drawing.Color.Red, 3);
Rectangle myRectangle = new Rectangle(mousepos.X - 125, mousepos.Y - 100, 250, 200);
graphicsObj.DrawRectangle(myPen, myRectangle);
}
private void Form1_MouseClick(object sender, MouseEventArgs e)
{
var relativePoint = this.PointToClient(Cursor.Position);
if (global_draw_redbox)
{
//Draw the object based on the mouse position
redbox(relativePoint);
//Reset the flag so we draw just one
global_draw_redbox = false;
}
else
{
MessageBox.Show("No object selected");
}
}
private void Form1_MouseDoubleClick(object sender, MouseEventArgs e)
{
MessageBox.Show("Test Mouse Double Click");
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
var relativePoint = this.PointToClient(Cursor.Position);
XY_Mouse_Position.Text = relativePoint.ToString();
}
private void boxToolStripMenuItem_Click(object sender, EventArgs e)
{
global_draw_redbox = true;
}
}
I want to use the FillEllipse & DrawEllipse function to act like a LED display. But I was not able to click on the button to disable the blinking again since the subroutine is still running. Any recommendation?
bool alert = false;
bool blink = false;
private void blinking()
{
Graphics pb = pictureBox1.CreateGraphics();
SolidBrush red = new SolidBrush(Color.Red);
SolidBrush green = new SolidBrush(Color.LightGreen);
while (blink == true)
{
pictureBox1.Refresh();
if (alert == true)
{
pb.FillEllipse(red, 20, 20, 50, 50);
alert = false;
}
else
{
//pb.FillEllipse(green, 20, 20, 50, 50);
pb.DrawEllipse(Pens.Red, 20, 20, 50, 50);
alert = true;
}
Thread.Sleep(timer1.Interval);
}
}
private void blink_btn_Click(object sender, EventArgs e)
{
if (blink == false)
{
blink = true;
}
else
{
blink = false;
}
blinking();
}
Besides that you are blocking the UI with your blinking() method, you're not drawing correctly anyway. You should only draw when handling a Paint event. Also, there's not really a good reason to use a PictureBox if all you're going to do is draw something yourself. Just put a Panel, or even make a custom control.
But, sticking with the "draw into the PictureBox" approach, this is what your code really ought to look like:
First, it looks like you already have a Timer attached to the form. Why you're not already using that is beyond me, but you should. Hook up a handler to the Tick event:
private void timer1_Tick(object sender, EventArgs e)
{
alert = !alert;
pictureBox1.Invalidate();
}
Add your handler for the PictureBox.Paint event:
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
Brush brush = alert ? Brushes.Red : Brushes.LightGreen;
e.Graphics.FillEllipse(brush, 20, 20, 50, 50);
}
Finally, use your button Click handler to toggle the timer:
private void blink_btn_Click(object sender, EventArgs e)
{
timer1.Enabled = !timer1.Enabled;
}
Add code as necessary to draw differently (the above just toggles between the red and green ellipse), to reset the appearance when the timer's not active, etc.
i am planning to write something on a picture box.in the page load event i am able to do that.
Graphics g = Graphics.FromImage(pictureBox1.Image);
Font font = new Font("Courier New", 6);
payagainst = "PARADISE TRADING, CONT & REAL ESTATE";
g.DrawString(payagainst, font, new SolidBrush(Color.Black), pagainstX, pagainstY);
My requirement is there is two textbox in the form ie to mention the the X and Y coordinates of the newly drawn label. If the user changes the values in the textbox position of the label has to be changed according to the values given in the text box. in the text box leave event i have written the code as follows. but its not working. whats the correct method to achieve this.
private void txtpaX_Leave(object sender, EventArgs e)
{
if (flag != 0)
{
Graphics gs = Graphics.FromImage(pictureBox1.Image);
Font font = new Font("Courier New", 6);
payagainst = "PARADISE TRADING, CONT & REAL ESTATE";
amount = 3300;
gs.DrawString(payagainst, font, new SolidBrush(Color.Black), float.Parse(txtpaX.Text), float.Parse(txtpaY.Text));
flag = 1;
}
}
any help will be appreciated
What is supposed to happen after the string is printed over the image?
Do you need to save the image or pass it on or is the display in the PictureBox the only aim?
For the latter case this is the way to do it:
You place the drawing code only in the Paint event and call it, by invalidating the PictureBox, either whenever the TextBoxes have a change or when you leave them..:
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawString(yourText, yourFont, yourBrush,
float.Parse(textBox1.Text), float.Parse(textBox2.Text));
}
// this will show up only after leaving the textbox:
private void textBox_Leave(object sender, EventArgs e)
{
pictureBox1.Invalidate();
}
// this will provide a live change:
private void textBox_TextChanged(object sender, EventArgs e)
{
pictureBox1.Invalidate();
}
Note that you should hook this code to both TextBoxes!
This code will persist the drawing but it will not change the actual Bitmap. Which I guess wouldn't make sense until you know exactly where the text should go..
If you want to change the actual Image you can do it like this:
private void stampButton_Click(object sender, EventArgs e)
{
using (Graphics G = Graphics.FromImage(pictureBox1.Image))
G.DrawString(yourText, yourFont, yourBrush,
float.Parse(textBox1.Text), float.Parse(textBox2.Text));
}
..and then maybe save it like this:
private void saveButton_Click(object sender, EventArgs e)
{
pictureBox1.Image.Save("yourfilename", System.Drawing.Imaging.ImageFormat.yourfileformat);
}
OK, I fix everything, now is exactly what I want.
I have a textBox1, panel1, and drawTexta (a button).
When I click the button and choose a point in the panel, I want to draw the string from the textBox1.
private void panel1_Paint(object sender, PaintEventArgs e)
{
using (SolidBrush br = new SolidBrush(Color.Red))
{
StringFormat sf = new StringFormat();
sf.FormatFlags = StringFormatFlags.DirectionRightToLeft;
e.Graphics.DrawString(textBox1.Text, this.Font, br, point1, sf);
}
}
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
point1 = new Point(e.X, e.Y);
}
bool flag = false;
Point point1 = new Point();
private void drawTexta_Click(object sender, EventArgs e)
{
flag = true;
panel1.Refresh();
}
The text isn't being drawn to panel1 because you need to refresh it.
Add this code to button1_Click, after you set drawText to true:
panel1.Refresh();
That will make the static text show up.
i need to animate an object in c# windows application
int l_nCircleXpos = 9, l_nCircleYpos = 0;
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics l_objGraphics = this.CreateGraphics();
Pen l_circlePen = new Pen(Color.Blue);
SolidBrush l_circleBrush = new SolidBrush(Color.Blue);
l_objGraphics.DrawEllipse(l_circlePen, l_nCircleXpos, l_nCircleYpos, 30, 30);
l_objGraphics.FillEllipse(l_circleBrush, l_nCircleXpos, l_nCircleYpos, 30, 30);
Pen l_rectPen = new Pen(Color.Red);
}
private void timer1_Tick(object sender, EventArgs e)
{
l_nCircleXpos++;
l_nCircleYpos++;
}
private void timer2_Tick(object sender, EventArgs e)
{
Invalidate();
}
but in timer2 its invalidating the entire form. i need to invalidate the specific circle area only.
please help to do this in a better way
You can pass a Rectangle (or better, a Region) as a parameter to Invalidate, to invalidate only the area you need to refresh :
Region region = /* region you need to refresh */;
this.Invalidate(region);