How to add textboxs to the dynamically created pictureboxes - c#

I have a program which dynamically creates movable pictureboxes when I click on buttons. I need to do something like when I click on the picturebox, this click adds to my dynamically created picturebox a new textbox when I can write descripiton of this picturebox(name,...). This textbox should be able to move with picturebox.
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
List<PictureBox> pictureboxes = new List<PictureBox>();
public Form1()
{
InitializeComponent();
}
private void AddPictureBox(string imagePath)
{
var pb = new PictureBox();
pb.Name = "picturebox" + pictureboxes.Count;
pb.Location = new Point(pictureboxes.Count * 100, 100);
pb.Size = new Size(70, 70);
pb.BorderStyle = BorderStyle.None;
pb.SizeMode = PictureBoxSizeMode.StretchImage;
this.Controls.Add(pb);
pb.Image = Image.FromFile(imagePath);
pb.Refresh();
pb.MouseDown += new MouseEventHandler(picMouseDown);
pb.MouseMove += new MouseEventHandler(picMouseMove);
pb.MouseUp += new MouseEventHandler(picMouseUp);
pictureboxes.Add(pb);
Invalidate();
}
private void router_Click(object sender, EventArgs e)
{
AddPictureBox(#"D:\\router.jpg");
}
private void Form1_Load(object sender, EventArgs e)
{
}
int x = 0;
int y = 0;
bool drag = false;
private void picMouseDown(object sender, MouseEventArgs e)
{
// Get original position of cursor on mousedown
x = e.X;
y = e.Y;
drag = true;
}
private void picMouseMove(object sender, MouseEventArgs e)
{
if (drag)
{
PictureBox pb = (PictureBox)sender;
// Get new position of picture
pb.Top += e.Y - y;
pb.Left += e.X - x;
pb.BringToFront();
Invalidate();
}
}
private void picMouseUp(object sender, MouseEventArgs e)
{
drag = false;
}
private void switch1_Click(object sender, EventArgs e)
{
AddPictureBox(#"D:\HP ProBook 450\Desktop\Grafika\switch1.png");
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
}
private void pc_Click(object sender, EventArgs e)
{
AddPictureBox(#"D:\HP ProBook 450\Desktop\pc.jpg");
}
private void server_Click(object sender, EventArgs e)
{
AddPictureBox(#"D:\HP ProBook 450\Desktop\server.png");
}
}
Thanks for any help :).

You can add a TextBox to a PictureBox in code like this:
TextBox newTextBox = new TextBox();
newTextBox.Parent = yourPictureBox;
// place it e.g. to the left bottom:
newTextBox.Location = new Point(10, yourPictureBox.Height - newTextBox.Height);
Note that this will add the TextBox to the Controls collection of the PB; so it will sit on top of the PictureBox; so, yes, it will move with the PictureBox but it will also hide a part or the PB!
If instead you simply want to group them, add them both to something like a Panel, again by setting that as their Parent!
Also note that you can't do this in the Designer; PictureBox is not really meant to act as a Container..
It doesn't matter how the PictureBox was created, as long as you have a reference to it.

Related

What is best way to write in windows forms with pen-tablet like wacom intuos in C#

i have a problem.
I'm writing a program that writes on it with a stylus.
First, i create a windows form with a panel.
second, this code:
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Collections;
using System.Diagnostics;
using System.Drawing.Drawing2D;
namespace testWrite
{
public partial class Form1 : Form
{
Graphics g;
int x = -1;
int y = -1;
bool moving = false;
Pen pen;
public Form1()
{
InitializeComponent();
g = panel1.CreateGraphics();
pen = new Pen(Color.Black, 5);
pen.SetLineCap(System.Drawing.Drawing2D.LineCap.Round, System.Drawing.Drawing2D.LineCap.Round, System.Drawing.Drawing2D.DashCap.Round);
pen.StartCap = System.Drawing.Drawing2D.LineCap.Round;
pen.EndCap = System.Drawing.Drawing2D.LineCap.Round;
}
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
if(e.Button == MouseButtons.Left)
{
g.DrawLine(pen, new Point(x, y), e.Location);
x = e.X;
y = e.Y;
}
}
private void panel1_MouseUp(object sender, MouseEventArgs e)
{
x = -1;
y = -1;
moving = false;
}
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
x = e.X;
y = e.Y;
moving = true;
}
}
}
I use this app with a Wacom intuos
But the result is not so good because a few words are lost...haizzz
toi tên la trần
quang hieu
hello heloo
especially, when i write fast or the text is small.
when i write in Microsoft Paint, it is very good
What is best way to to write in windows forms with pen-tablet like wacom intuos?
UPDATE 1:
With cmt from TaW.
Thanks for your help. But, that's not what I need...
i was change my code to:
public partial class Form1 : Form
{
List<Point> curPoints = new List<Point>();
List<List<Point>> allPoints = new List<List<Point>>();
public Form1()
{
InitializeComponent();
}
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button != MouseButtons.Left) return;
// here we should check if the distance is more than a minimum!
curPoints.Add(e.Location);
// let it show
panel1.Invalidate();
}
private void panel1_MouseUp(object sender, MouseEventArgs e)
{
if (curPoints.Count > 1)
{
// ToList creates a copy
allPoints.Add(curPoints.ToList());
curPoints.Clear();
}
}
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
if (curPoints.Count > 1)
{
// begin fresh line or curve
curPoints.Clear();
// startpoint
curPoints.Add(e.Location);
}
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
// here you can use DrawLines or DrawCurve
// current line
if (curPoints.Count > 1) e.Graphics.DrawCurve(Pens.Red, curPoints.ToArray());
// other lines or curves
foreach (List<Point> points in allPoints)
if (points.Count > 1) e.Graphics.DrawCurve(Pens.Red, points.ToArray());
}
}
But nothing better. The result is worse...
I tried to write: "Hello my name is Hieu", but is not run...
Looks like a pen-tablet differs from a mouse when use to write. Because, with mouse i feel that is better in this code...
UPDATE 2:
With code by Idle_Mind. It will be fine if i set pen-tablet:
With setting "Click", it is not OK
How to fix it, i don't want to set "Double Click" to my pen !
Here's my version...worked great for me. You might need to adjust your tablet settings so that it picks up everything correctly:
public partial class FormTablet : Form
{
private Point lastPoint;
private GraphicsPath GP = null;
private List<GraphicsPath> GPs = new List<GraphicsPath>();
public FormTablet()
{
InitializeComponent();
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
pictureBox1.Invalidate();
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
lastPoint = new Point(e.X, e.Y);
GP = new GraphicsPath();
GP.AddLine(lastPoint, lastPoint);
GPs.Add(GP);
}
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
Point pt = new Point(e.X, e.Y);
GP.AddLine(lastPoint, pt);
lastPoint = pt;
pictureBox1.Invalidate();
}
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
GP = null;
pictureBox1.Invalidate();
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (checkBox1.Checked)
{
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
}
using(Pen p = new Pen(Color.Black, (int)numericUpDown1.Value))
{
p.LineJoin = LineJoin.Round;
p.MiterLimit = p.Width / 2;
foreach (GraphicsPath path in GPs)
{
if (path.PathPoints.Count() > 2)
{
// draw the path
e.Graphics.DrawPath(p, path);
}
else
{
// just draw a single dot
Rectangle rc = new Rectangle(Point.Round(path.PathPoints[0]), new Size(1, 1));
rc.Inflate((int)numericUpDown1.Value, (int)numericUpDown1.Value);
e.Graphics.FillEllipse(Brushes.Black, rc);
}
}
}
}
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
pictureBox1.Invalidate();
}
private void button1_Click(object sender, EventArgs e)
{
GPs.Clear();
pictureBox1.Invalidate();
}
}

How to make picture box move across screen

I am trying to make my picturebox move across the screen but I have this error: 'picture' does not exist in the current context inside the timer. What can I do?
private void Button1_Click(object sender, EventArgs e)
{
var picture = new PictureBox
{
Name = "pictureBox",
Size = new Size(20, 20),
Location = new System.Drawing.Point(x, y),
Image = image1,
};
this.Controls.Add(picture);
timer1.Enabled = true;
}
private void Timer1_Tick(object sender, EventArgs e)
{
//redefine pictureBox position.
x = x - 50;
picture.Location = new System.Drawing.Point(x, y); //'picture' does not exist in the current context
}
Well, picture is a local variable and thus is not visible outside Button1_Click. Let's turn it into a field:
// now picture is a private field, visible within th class
//TODO: do not forget to Dispose it
private PictureBox picture;
private void Button1_Click(object sender, EventArgs e)
{
if (picture != null) // already created
return;
picture = new PictureBox
{
Name = "pictureBox",
Size = new Size(20, 20),
Location = new System.Drawing.Point(x, y),
Image = image1,
Parent = this, // instead of this.Controls.Add(picture);
};
timer1.Enabled = true;
}
private void Timer1_Tick(object sender, EventArgs e)
{
//redefine pictureBox position.
x = x - 50;
if (picture != null) // if created, move it
picture.Location = new System.Drawing.Point(x, y);
}
Try putting the picture outside of the button click like this:
PictureBox picture;
private void Button1_Click(object sender, EventArgs e)
{
picture = new PictureBox
{
Name = "pictureBox",
Size = new Size(20, 20),
Location = new System.Drawing.Point(x, y),
Image = image1,
};
this.Controls.Add(picture);
timer1.Enabled = true;
}
private void Timer1_Tick(object sender, EventArgs e)
{
//redefine pictureBox position.
x = x - 50;
if(picture != null)
picture.Location = new System.Drawing.Point(x, y);
}

Why can't I paint a rectangle with this code in pictureBox?

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 UTUResultWithCoordinates
{
public partial class GetCoordinates : Form
{
private string sem;
private string branch;
private int mouseisdown = 0;
private int recx = 0;
private int recy = 0;
private int mousemovingwhilepressed = 0;
public GetCoordinates()
{
InitializeComponent();
}
public GetCoordinates(string p, string p_2)
{
// TODO: Complete member initialization
InitializeComponent();
branch = p;
sem = p_2;
pictureBox1.Controls.Add(pictureBox2);
pictureBox2.Location = new Point(0, 0);
pictureBox2.BackColor = Color.Transparent;
pictureBox2.Width = 1191;
pictureBox2.Height = 842;
}
private void GetCoordinates_Load(object sender, EventArgs e)
{
pictureBox1.ImageLocation = #"D:\DotNet\UTUResultWithCoordinates\UTUResultWithCoordinates\bin\Debug\ComputerScience6.jpg";
}
private void pictureBox2_Paint(object sender, PaintEventArgs e)
{
if (mouseisdown == 1 && mousemovingwhilepressed==1)
{
System.Drawing.Graphics graphicsObj;
graphicsObj = this.CreateGraphics();
Pen myPen = new Pen(System.Drawing.Color.Blue, 100);
Rectangle myRectangle = new Rectangle(recx, recy, 20, 20);
e.Graphics.DrawRectangle(myPen, myRectangle);
}
}
private void pictureBox2_MouseDown(object sender, MouseEventArgs e)
{
mouseisdown = 1;
recx = e.X;
recy = e.Y;
pictureBox2.CreateGraphics();
}
private void pictureBox2_MouseMove(object sender, MouseEventArgs e)
{
label1.Text = e.X + "," + e.Y;
mousemovingwhilepressed = 1;
recx = e.X;
recy = e.Y;
pictureBox2.CreateGraphics();
}
private void pictureBox2_MouseUp(object sender, MouseEventArgs e)
{
mousemovingwhilepressed = 0;
mouseisdown = 0;
pictureBox2.CreateGraphics();
}
}
}
I have created a pictureBox1 in which an image is displayed. Then I have created a pictureBox2 inside it so that I can paint on that image a rectangle by dragging the mouse. But nothing is happening on clicking the mouse. What is the error?
Calling CreateGraphics does not trigger the painting of the PictureBox.
Use Invalidate to cause a redraw.
For a full example see: How to select an area on a PictureBox.Image with mouse in C#
Side notes:
Calling InitializeControl in a method other than the constructor is not a good idea.
when you need a boolean use a boolean, not an integer.
Objects that implement IDisposable (such as Pen) should be created as few times as possible and be disposed when no longer needed/used.

WPF contextMenu control for bring forward and send backward

Having trouble with something here which I'm hoping is actually simple.
I have a custom UserControl in WPF which allows me to display an image. When the program is running a user can add this UserControl as many times as they like to a canvas. In effect a simple image viewer where they can add and move images about.
I would like to be able to right click these images open a contextMenu and then choose send backward of bring forward and the images would then change z order depending which menu choice was clicked.
I have the user control set up with the contextMenu so I just need to know the code for changing the z order of this userControl...
Any help is much appreciated :)
namespace StoryboardTool
{
/// <summary>
/// Interaction logic for CustomImage.xaml
/// </summary>
public partial class CustomImage : UserControl
{
private Point mouseClick;
private double canvasLeft;
private double canvasTop;
public CustomImage()
{
InitializeComponent();
cusImageControl.SetValue(Canvas.LeftProperty, 0.0);
cusImageControl.SetValue(Canvas.TopProperty, 0.0);
}
public void chooseImage()
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Title = "Choose Image to Add";
if (ofd.ShowDialog() == true)
{
BitmapImage bImage = new BitmapImage();
bImage.BeginInit();
bImage.UriSource = new Uri(ofd.FileName);
bImage.EndInit();
image.Width = bImage.Width;
image.Height = bImage.Height;
image.Source = bImage;
image.Stretch = Stretch.Fill;
}
}
private void cusImageControl_LostMouseCapture(object sender, MouseEventArgs e)
{
((CustomImage)sender).ReleaseMouseCapture();
}
private void cusImageControl_MouseUp(object sender, MouseButtonEventArgs e)
{
((CustomImage)sender).ReleaseMouseCapture();
cusImageControl.Cursor = Cursors.Arrow;
}
private void cusImageControl_MouseMove(object sender, MouseEventArgs e)
{
if ((((CustomImage)sender).IsMouseCaptured) && (cusImageControl.Cursor == Cursors.SizeAll))
{
Point mouseCurrent = e.GetPosition(null);
double Left = mouseCurrent.X - mouseClick.X;
double Top = mouseCurrent.Y - mouseClick.Y;
mouseClick = e.GetPosition(null);
((CustomImage)sender).SetValue(Canvas.LeftProperty, canvasLeft + Left);
((CustomImage)sender).SetValue(Canvas.TopProperty, canvasTop + Top);
canvasLeft = Canvas.GetLeft(((CustomImage)sender));
canvasTop = Canvas.GetTop(((CustomImage)sender));
}
else if ((((CustomImage)sender).IsMouseCaptured) && (cusImageControl.Cursor == Cursors.SizeNWSE))
{
/*Point mouseCurrent = e.GetPosition(null);
cusImageControl.Height = cusImageControl.canvasTop + mouseClick.Y;
cusImageControl.Width = cusImageControl.canvasLeft + mouseClick.X;
mouseClick = e.GetPosition(null);*/
}
}
private void cusImageControl_MouseDown(object sender, MouseButtonEventArgs e)
{
mouseClick = e.GetPosition(null);
canvasLeft = Canvas.GetLeft(((CustomImage)sender));
canvasTop = Canvas.GetTop(((CustomImage)sender));
((CustomImage)sender).CaptureMouse();
}
private void ContextMenuBringForward_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Bring Forward");
}
private void ContextMenuSendBackward_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Send Backward");
}
private void ContextMenuMove_Click(object sender, RoutedEventArgs e)
{
cusImageControl.Cursor = Cursors.SizeAll;
}
private void ContextMenuResize_Click(object sender, RoutedEventArgs e)
{
cusImageControl.Cursor = Cursors.SizeNWSE;
}
}
}
See Panel attached property Canvas.SetZIndex. Change z-Index of all elements to 0, and z-Index of your right-clicked control to 1.
void mouseUp(object sender, MouseButtonEventArgs e)
{
foreach (var child in yourCanvas.Children) Canvas.SetZIndex(child, 0);
Canvas.SetZIndex((UIElement)sender, 1);
}
The following code works where selected is defined as my UserControl and set in the mouseDown event.
private void ContextMenuSendBackward_Click(object sender, RoutedEventArgs e)
{
Canvas parent = (Canvas)LogicalTreeHelper.GetParent(this);
foreach (var child in parent.Children)
{
Canvas.SetZIndex((UIElement)child, 0);
}
Canvas.SetZIndex(selected, 1);
}
Thanks to voo for all his help.

How to get the Coordinates of a Custom Image Cursor in c#?

Bitmap hh = (Bitmap)System.Drawing.Bitmap.FromFile("example.png");
Graphics.FromImage(hh);
IntPtr ptr = hh.GetHicon();
Cursor c = new Cursor(ptr);
this.Cursor = c;
I use this code to create a custom image cursor. I want to retrieve the coordinates of this custom image cursor when on a Click event. So that these coordinates can be used to draw the image of this cursor in a picture box when clicked on the image loaded in the picture box. I'm doing this in C#.
I tried another approach
public partial class Form1 : Form
{
private Bitmap _bmp = new Bitmap(250, 250);
public Form1()
{
InitializeComponent();
panel1.MouseDown += new MouseEventHandler(panel1_MouseDown);
panel1.Paint += new PaintEventHandler(panel1_Paint);
using (Graphics g = Graphics.FromImage(_bmp))
g.Clear(SystemColors.Window);
}
private void pictureBox1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
Point mouseDownLocation = new Point(e.X, e.Y);
label1.Text = mouseDownLocation.X.ToString();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawImage(_bmp, new Point(0, 0));
}
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
using (Graphics g = Graphics.FromImage(_bmp))
{
g.DrawString("Mouse Clicked Here!", panel1.Font, Brushes.Black, e.Location);
}
panel1.Invalidate();
}
private void button1_Click(object sender, EventArgs e)
{
panel1.Image.Save(#"C:\test.jpg", ImageFormat.Jpeg);
}
But when i try so save the image i get an Exception: Object reference not set to an instance of an object.
Please note that panel1 in the code above refers to a picture box
To get the coordinates of the mouse on a PictureBox you should not handle the OnClick event but the OnMouseDown, for example in this way:
private void pb_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
Point mouseDownLocation = new Point(e.X, e.Y);
}
now you have the mouseDownLocation which contains the coordinates you were looking for.
i know the way to get the coordinate of mouse you can code it like
Cursor.Position.X and Cursor.Position.Y to get the Coordinate under the mouse

Categories

Resources