Drawing a straight line in C# windows form - c#

I have a simple windows forms program which allows the user to draw straight lines in a picture box. There is a line, but it goes out of the picture box and is not visible within it (like in the picture i attached). How can i make it so line shows up only in the picture box. 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;
using System.Windows.Input;
namespace LinePOD
{
public partial class LineTest : Form
{
public LineTest()
{
InitializeComponent();
}
Point p1 = new Point();
Point p2 = new Point();
Pen pen = new Pen(Color.Magenta, 10);
private void LineTest_Load(object sender, EventArgs e)
{
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
p1 = e.Location;
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
p2 = e.Location;
Graphics g = this.CreateGraphics();
g.DrawLine(pen, p1, p2);
}
}
private void pictureBox1_Click(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
pictureBox1.BackColor = Color.Aqua;
}
}
}

You may create a bitmap with same size of PictureBox and draw that bitmap in the Paint event of PictureBox. Then draw lines to bitmap in your mouse events. This retains lines in windows minimize/restore events. I put entire code for convenience:
public partial class Form1 : Form
{
Bitmap bitmap;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
bitmap = new Bitmap(pictureBox1.ClientSize.Width,
pictureBox1.ClientSize.Height,
System.Drawing.Imaging.PixelFormat.Format32bppArgb);
}
Point p1 = new Point();
Point p2 = new Point();
Pen pen = new Pen(Color.Magenta, 10);
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
p1 = e.Location;
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
p2 = e.Location;
Graphics g = Graphics.FromImage(bitmap);
g.DrawLine(pen, p1, p2);
pictureBox1.Invalidate();
g.Dispose();
}
}
private void button1_Click(object sender, EventArgs e)
{
pictureBox1.BackColor = Color.Aqua;
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawImage(bitmap, 0, 0, bitmap.Width, bitmap.Height);
}
}

Related

Problems with Image Tag in Picturebox

So, i try to learn how to Drag and Drop an Image from one PictureBox to another and that works well. But how can i drag and drop the Image TAG from pictureox1 to picturebox2?
i currently have 3 source images and 3 drop boxes.
the dropbox6 is locked with a countdown after a buttonclick (see button2)
(later i will lock all dropboxes)
after i hit this button a countdown starts and if the countdown is 0 (ZERO) only then i can drag one of the 3 images to this box.
however, i have given each of these 3 images in the souceboxes a TAG name.
how can i drop this tagname also to the dropbox?
here is what i have so far:
(the Label labeled "Counter" is actually Label4 in the 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 Game
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void pictureBox_MouseDown(object sender, MouseEventArgs e)
{
// pictureBox1.DoDragDrop(pictureBox1.Image, DragDropEffects.Copy);
((PictureBox)sender).DoDragDrop(((PictureBox)sender).Image, DragDropEffects.Copy);
}
private void Form1_Load(object sender, EventArgs e)
{
pictureBox4.AllowDrop = true;
pictureBox5.AllowDrop = true;
pictureBox6.AllowDrop = true;
pictureBox6.Enabled = false;
}
private void pictureBox4_DragEnter(object sender, DragEventArgs e)
{
if(e.Data.GetDataPresent(DataFormats.Bitmap))
{
e.Effect = DragDropEffects.Copy;
}
}
private void pictureBox4_DragLeave(object sender, EventArgs e)
{
}
private void pictureBox4_DragDrop(object sender, DragEventArgs e)
{
Image getPicture = (Bitmap) e.Data.GetData(DataFormats.Bitmap);
pictureBox4.Image = getPicture;
}
private void pictureBox5_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.Bitmap))
{
e.Effect = DragDropEffects.Copy;
}
}
private void pictureBox5_DragLeave(object sender, EventArgs e)
{
}
private void pictureBox5_DragDrop(object sender, DragEventArgs e)
{
Image getPicture = (Bitmap)e.Data.GetData(DataFormats.Bitmap);
pictureBox5.Image = getPicture;
}
private void pictureBox6_DragDrop(object sender, DragEventArgs e)
{
Image getPicture = (Bitmap)e.Data.GetData(DataFormats.Bitmap);
pictureBox6.Image = getPicture;
timer1.Enabled = false;
}
private void pictureBox6_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.Bitmap))
{
e.Effect = DragDropEffects.Copy;
timer1.Enabled = false;
}
}
private void pictureBox6_DragLeave(object sender, EventArgs e)
{
timer1.Enabled = false;
}
private void pictureBox4_Click(object sender, EventArgs e)
{
MessageBox.Show("test");
}
private void timer1_Tick(object sender, EventArgs e)
{
counter--;
if (counter == 0)
timer1.Stop();
label4.Text = counter.ToString();
if(counter == 0)
{
pictureBox6.Enabled = true;
label4.Enabled = false;
timer1.Stop();
}
}
private void button1_Click(object sender, EventArgs e)
{
System.Windows.Forms.Application.Exit();
}
private void pictureBox6_Click(object sender, EventArgs e)
{
MessageBox.Show(pictureBox6.Tag.ToString());
}
private int counter = 3;
private void button2_Click(object sender, EventArgs e)
{
int counter = 3;
timer1 = new Timer();
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Interval = 1000; // 1 second
timer1.Start();
label4.Text = counter.ToString();
if(label4.Text == "0")
{
timer1.Stop();
}
pictureBox6.Image = Properties.Resources.shoreSite_d_1_l_x_x;
button2.Visible=false;
}
}
internal class bild1
{
private Bitmap shoreSite_d_1_l_x_x;
public bild1(Bitmap shoreSite_d_1_l_x_x)
{
this.shoreSite_d_1_l_x_x = shoreSite_d_1_l_x_x;
}
}
}
In MouseDown you are saying what you want to transmit in the DoDragDrop call. In your current case you are transmitting the image ((PictureBox)sender).Image but you can chose to transmit the tag as well...
private void pictureBox_MouseDown(object sender, MouseEventArgs e)
{
((PictureBox)sender).DoDragDrop(((PictureBox)sender).Image, DragDropEffects.Copy);
((PictureBox)sender).DoDragDrop(((PictureBox)sender).Tag, DragDropEffects.Copy);
}
...Then make sure to parse for each possible input type in DragDrop
private void pictureBox6_DragDrop(object sender, DragEventArgs e)
{
var image = e.Data.GetData(DataFormats.Bitmap) as Bitmap;
var tag = e.Data.GetData(DataFormats.Text) as string;
if (image != null)
{
pictureBox4.Image = image;
}
if (tag != null)
{
pictureBox4.Tag = tag;
}
timer1.Enabled = false;
}
Beware, that you will need to update all the code that checks that the data is Bitmap before it arrives at DragDrop ie in DragEnter and write code that handles both Bitmap and Text, otherwise the Drag functionality will break.
AWESOME!!
It works now. I will continue this Project.

Missing the User Control in Windows Form And the Tool Box?

I have created a Desktop app using Windows Form (c#) in visual Studio 2019.first, in my form I created a panel and several buttons for navigation. for the crud, I have created a user control and now I need to get this user control to the form but it shows in the toolbox neither in the codes
form Home
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;
using System.Runtime.InteropServices;
namespace WinFormsApp1
{
public partial class Home : Form
{
static Home _obj;
[DllImport("Gdi32.dll", EntryPoint = "CreateRoundRectRgn")]
private static extern IntPtr CreateRoundRectRgn
(
int nLeftRect, // x-coordinate of upper-left corner
int nTopRect, // y-coordinate of upper-left corner
int nRightRect, // x-coordinate of lower-right corner
int nBottomRect, // y-coordinate of lower-right corner
int nWidthEllipse, // height of ellipse
int nHeightEllipse // width of ellipse
);
public static Home Instance
{
get {
if (_obj == null) {
_obj = new Home();
}
return _obj;
}
}
public Home()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.Region = System.Drawing.Region.FromHrgn(CreateRoundRectRgn(0, 0, Width, Height, 20, 20));
panel2.Height = 46;
btnSideAdd.Visible = false;
_obj = this;
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
this.Region = System.Drawing.Region.FromHrgn(CreateRoundRectRgn(0, 0, Width, Height, 20, 20));
}
public Button BtnSideAdd {
get { return btnSideAdd; }
set { btnSideAdd = value; }
}
public Panel PanelControl1
{
get { return PanelControl1; }
set { PanelControl1 = value; }
}
private void label1_Click(object sender, EventArgs e)
{
}
private void button4_Click(object sender, EventArgs e)
{
sidePanel.Height = button4.Height;
sidePanel.Top = button4.Top;
}
private void button5_Click(object sender, EventArgs e)
{
sidePanel.Height = button5.Height;
sidePanel.Top = button5.Top;
}
private void button7_Click(object sender, EventArgs e)
{
sidePanel.Height = button7.Height;
sidePanel.Top = button7.Top;
}
private void button10_Click(object sender, EventArgs e)
{
sidePanel.Height = button10.Height;
sidePanel.Top = button10.Top;
}
private void button2_Click(object sender, EventArgs e)
{
sidePanel.Height = button2.Height;
sidePanel.Top = button2.Top;
}
private void button1_Click(object sender, EventArgs e)
{
sidePanel.Height = btnSideAdd.Height;
sidePanel.Top = btnSideAdd.Top;
}
private void button8_Click(object sender, EventArgs e)
{
if (panel2.Height == 140)
{
panel2.Height = 46;
}
else
{
panel2.Height = 140;
}
}
private void panel2_Paint(object sender, PaintEventArgs e)
{
}
private void panel2_Paint_1(object sender, PaintEventArgs e)
{
}
private void button11_Click(object sender, EventArgs e)
{
}
private void button12_Click(object sender, EventArgs e)
{
}
private void button6_Click(object sender, EventArgs e)
{
sidePanel.Height = button6.Height;
sidePanel.Top = button6.Top;
}
private void button3_Click(object sender, EventArgs e)
{
sidePanel.Height = button3.Height;
sidePanel.Top = button3.Top;
}
private void button9_Click(object sender, EventArgs e)
{
sidePanel.Height = button9.Height;
sidePanel.Top = button9.Top;
}
}
}
user control AddWorks
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace WinFormsApp1.Asram
{
public partial class AddWork : UserControl
{
public AddWork()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
}
private void label5_Click(object sender, EventArgs e)
{
}
private void label3_Click(object sender, EventArgs e)
{
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
}
private void label1_Click(object sender, EventArgs e)
{
}
}
}
Im a beginner and this my assignment project I need to fix this so that I can move in to other parts

Numericupdown box line width

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 MiniPaint
{
public partial class Form1 : Form
{
Graphics g;
Pen p = new Pen(Color.Black, 1);
Point sp = new Point(0, 0);
Point ep = new Point(0, 0);
int k = 0;
public Form1()
{
InitializeComponent();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
}
private void red_Click(object sender, EventArgs e)
{
p.Color = red.BackColor;
default1.BackColor = red.BackColor;
}
private void green_Click(object sender, EventArgs e)
{
p.Color = green.BackColor;
default1.BackColor = green.BackColor;
}
private void blue_Click(object sender, EventArgs e)
{
p.Color = blue.BackColor;
default1.BackColor = blue.BackColor;
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
sp = e.Location;
if (e.Button == MouseButtons.Left);
k = 1;
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
k = 0;
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (k == 1)
{
ep = e.Location;
g = this.CreateGraphics();
g.DrawLine(p, sp, ep);
}
sp = ep;
}
private void del1_Click(object sender, EventArgs e)
{
g.Clear(Color.White);
}
private void yellow_Click(object sender, EventArgs e)
{
p.Color = yellow.BackColor;
default1.BackColor = yellow.BackColor;
}
private void purple_Click(object sender, EventArgs e)
{
p.Color = purple.BackColor;
default1.BackColor = purple.BackColor;
}
private void brown_Click(object sender, EventArgs e)
{
p.Color = brown.BackColor;
default1.BackColor = brown.BackColor;
}
private void black_Click(object sender, EventArgs e)
{
p.Color = black.BackColor;
default1.BackColor = black.BackColor;
}
private void nud1_ValueChanged(object sender, EventArgs e)
{
}
private void white_Click(object sender, EventArgs e)
{
p.Color = white.BackColor;
default1.BackColor = white.BackColor;
}
}
}
I'm almost done with my minipaint code in c#. I wanted to add one more thing to it and it's that I can change the thickness(width) of the line im going to draw via numericupadown box and I'm trying to make it work for over an hour. Can someone help me with it please and is there a simple way of doing it? ( nud1 is the numereric updown box)
On numeric up down value changed event, change the thickness of the pen you're using, I would recommend storing the current color in a variable that you can assign back to your pen on the value changed event when you re-initialize.
This MSDN link shows details on the Pen class from System.Drawing.
p = new Pen(Color, (float)nud1.Value);

Repeated point creation

I am using MousePosition to try to determine which way the user moves his or her mouse after the MouseDown event is triggered. The problem is I am trying to make a starting variable using Point datatype and I only want this Point to be filled with data once but I have it in a MouseDown so I can use the mouse arguments e.X and e.Y to determine where the MouseDown event was called. Here is an example of what im thinking of
public void panel1_MouseDown(object sender, MouseEventArgs e)
{
Point start = new Point(e.X, e.Y);
}
public void panel1_MouseMove(object sender, MouseEventArgs e)
{
if(MousePosition.X > start.X)
{
Console.WriteLine("you have moved right");
}
}
so how would I only create that start variable once while still having it have access to the e mouse argument. and also how would I access the variable between panel1_MouseDown and panel1_MouseMove? If you see a better alternative to doing this too that would be great! Thank you all for the help!
If you have aversion to define new class members (for some reason), this is the least you could have:
Point? start = null;
public void panel1_MouseDown(object sender, MouseEventArgs e)
{
start = new Point(e.X, e.Y);
}
public void panel1_MouseUp(object sender, MouseEventArgs e)
{
start = null;
}
public void panel1_MouseMove(object sender, MouseEventArgs e)
{
if(start.HasValue)
if(MousePosition.X > start.Value.X)
Console.WriteLine("you have moved right");
}
But for clarity (and functionality) I'd have an additional boolean variable:
bool mouseIsDown = false;
Point start;
public void panel1_MouseDown(object sender, MouseEventArgs e)
{
start = new Point(e.X, e.Y);
mouseIsDown = true;
}
public void panel1_MouseUp(object sender, MouseEventArgs e)
{
mouseIsDown = false;
}
public void panel1_MouseMove(object sender, MouseEventArgs e)
{
if(mouseIsDown)
if(MousePosition.X > start.X)
Console.WriteLine("you have moved right");
}
declare your start point as private class variable
Private Point start;
public void panel1_MouseDown(object sender, MouseEventArgs e)
{
this.start = new Point(e.X, e.Y);
}
public void panel1_MouseMove(object sender, MouseEventArgs e)
{
if(MousePosition.X > this.start.X)
{
Console.WriteLine("you have moved right");
}
}

change brush color with combobox

I need the comboBox index to change the color of the brush/pen when it is selected, I know it should be a simple fix, but I cant seem to get it.
public partial class Form1 : Form
{
private bool penDown = false;
private int radius = 5;
private SolidBrush brush = new SolidBrush(Color.IndianRed);
private Color[] colors = { Color.IndianRed, Color.Blue, Color.Green, Color.Yellow, Color.Purple};
public Form1()
{
InitializeComponent();
}
private void btnClr_Click(object sender, EventArgs e)
{
Graphics g = panel1.CreateGraphics();
g.Clear(panel1.BackColor);
g.DrawImage(panel1.BackgroundImage, panel1.ClientRectangle, 0, 0, panel1.BackgroundImage.Width,
panel1.BackgroundImage.Height, GraphicsUnit.Pixel);
g.Dispose();
}
private void btnQuit_Click(object sender, EventArgs e)
{
base.Close();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
if (!penDown)
{
return;
}
Graphics g = panel1.CreateGraphics();
g.FillEllipse(brush, new Rectangle(e.X - radius, e.Y - radius, 2 * radius, 2 * radius));
g.Dispose();
}
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
penDown = true;
}
private void panel1_MouseUp(object sender, MouseEventArgs e)
{
penDown = false;
}
private void colorCB_SelectedIndexChanged(object sender, EventArgs e)
{
//int i = ((color
}
}
Just use the combo box SelectedIndex property to retrieve the color from your colors array:
private void colorCB_SelectedIndexChanged(object sender, EventArgs e)
{
brush = new SolidBrush(colors[colorCB.SelectedIndex]);
}

Categories