I've been experimenting with adding elements to Windows Forms dynamically via code.
I need to create a PictureBox element. So, far, I have the following code:
private void Form1_Load(object sender, EventArgs e)
{
//stylise form
this.BackColor = System.Drawing.Color.Black;
PictureBox bgui = new PictureBox();
bgui.Image = Properties.Resources.attack_box;
bgui.Name = "bgui";
bgui.Location = new Point(0, 600);
this.Controls.Add(bgui);
bgui.Visible = true;
}
However, when this code is run, I get nothing but the black background which I set earlier. I've looked at many questions similar to mine; and they all say I need to add it to the control, which I have done, yet it still abstains from showing.
I would really appreciate it if you could give me an insight into my wrong-doing.
Thanks, Computo.
You need to set Width and Height Properties of the PictureBox.
Try This:
bgui.Width = 500;
bgui.Height = 500;
Complete Code:
private void Form1_Load(object sender, EventArgs e)
{
//stylise form
this.BackColor = System.Drawing.Color.Black;
PictureBox bgui = new PictureBox();
bgui.Image = Properties.Resources.attack_box;
bgui.Name = "bgui";
bgui.Width = 500;
bgui.Height = 500;
bgui.Location = new Point(0, 600);
this.Controls.Add(bgui);
bgui.Visible = true;
}
Turns out that System.Drawing.Point does not translate to the actual pixels on the screen. I will have to investigate how Point translates into pixels.
Here its works perfect. Specify the SizeMode and change the location.
private void Form1_Load(object sender, EventArgs e)
{
//stylise form
this.BackColor = System.Drawing.Color.Black;
PictureBox bgui = new PictureBox();
bgui.Image = Properties.Resources.attack_box;
bgui.Location = new System.Drawing.Point(100, 0);
bgui.Name = "pictureBox1";
bgui.SizeMode = PictureBoxSizeMode.AutoSize;
this.Controls.Add(bgui);
}
Related
I tried to change the values with this.Height and this.Width, but it didn't work after I clicked the button. Any idea why it's not working?
The PictureBox inside the Form worked with the same strategy though.
private void clear_ClickButton(object sender, EventArgs e)
{
pictureBox5.Image = null;
pictureBox5.Height = 500;
pictureBox5.Width = 672;
this.Width = 890;
this.Height = 662;
this.MaximizeBox = false;
pictureBox7.Enabled = false;
}
First at all, I assume you speak about WinForm.
Form1.Size = new System.Drawing.Size(890, 662);
For more info How to: Resize Windows Forms and Change form size at runtime in C#
I'm trying to create an array/list of picturebox objects that are declared and added to the form on button click (Meaning that I'm not creating multiple objects with my array, but plan to if I can get this to run). Not getting errors, but the pictureboxes themselves do not appear on the form.
private void spawn_Click(object sender, EventArgs e)
{
var pictureTest[0] = new PictureBox();
pictureTest[0].Image = Properties.Resources.testimage;
pictureTest[0].Location = new Point(500, 250);
pictureTest[0].Name = "spawn1";
pictureTest[0].Size = new Size(50, 50);
pictureTest[0].TabIndex = 98;
pictureTest[0].TabStop = false;
this.Controls.Add(pictureTest[0]);
}
Through the course of my research, I've mainly just gotten the advice to use this.Controls.Add, but that doesn't seem to be my issue here. My array is declared earlier with:
PictureBox[] pictureTest = new pictureTest[100];
As #HansPassant says in the comments, this code doesn't compile. The following should broadly do what you want:
int _position = 10;
private void spawn_Click(object sender, EventArgs e)
{
var pictureTest = new PictureBox();
pictureTest.Image = Properties.Resources.testimage;
pictureTest.Location = new Point(_position, 250);
pictureTest.Name = "spawn1";
pictureTest.Size = new Size(50, 50);
pictureTest.TabIndex = 98;
pictureTest.TabStop = false;
this.Controls.Add(pictureTest);
_position += 100;
}
Firstly, there's no need to maintain a separate array of PictureBox, as they are part of your form. Secondly, as #HansPassant said - you were overlaying the images directly on top of each other, so you couldn't tell if you had 1 or 1000.
I've been reading stackoverflow for a while now just to learn, and I've come across a situation where I can finally ask a question. I'm making a Simon Says type memory game, where I flash shapes at the user, and the user has to click a button in the same order the shapes were shown to them. I want to draw the shape that I'm drawing on the screen within the button that they are clicking because it's much easier to remember and compare shapes to shapes rather than shapes to a button that says the shapes name.
Hopefully my question is clear, and thanks for taking a look!
Yes, you can set the Image property of Button. Alternatively, you can draw non-rectangular buttons, that is, buttons of any shape. The following code demonstrates both techniques:
using System;
using System.Drawing;
using System.Windows.Forms;
class ShapeButton : Button {
public Action<PaintEventArgs> DoPaint { get; set; }
protected override void OnPaint(PaintEventArgs e) {
if (DoPaint != null) { DoPaint(e); }
}
}
static class Program {
static void Main() {
// Ellipse button
ShapeButton ellipseButton = new ShapeButton();
ellipseButton.Location = new Point(10, 10);
ellipseButton.Size = new Size(80, 80);
ellipseButton.DoPaint = delegate(PaintEventArgs e) {
Graphics graphics = e.Graphics;
SolidBrush brush1 = new SolidBrush(SystemColors.ButtonFace);
graphics.FillRectangle(brush1, 0, 0, ellipseButton.Width, ellipseButton.Height);
SolidBrush brush2 = new SolidBrush(Color.Red);
graphics.FillEllipse(brush2, 0, 0, ellipseButton.Width, ellipseButton.Height);
};
ellipseButton.Click += delegate(object sender, EventArgs e) {
MessageBox.Show("Ellipse!");
};
// Triangle button
ShapeButton triangleButton = new ShapeButton();
triangleButton.Location = new Point(100, 10);
triangleButton.Size = new Size(80, 80);
triangleButton.DoPaint = delegate(PaintEventArgs e) {
Graphics graphics = e.Graphics;
SolidBrush brush1 = new SolidBrush(SystemColors.ButtonFace);
graphics.FillRectangle(brush1, 0, 0, triangleButton.Width, triangleButton.Height);
SolidBrush brush2 = new SolidBrush(Color.Green);
Point[] points = {
new Point(triangleButton.Width / 2, 0),
new Point(0, triangleButton.Height),
new Point(triangleButton.Width, triangleButton.Height)
};
graphics.FillPolygon(brush2, points);
};
triangleButton.Click += delegate(object sender, EventArgs e) {
MessageBox.Show("Triangle!");
};
// Star button (using image)
Button starButton = new Button();
starButton.Location = new Point(190, 10);
starButton.Size = new Size(80, 80);
starButton.Image = new Bitmap("Star.png");
starButton.Click += delegate(object sender, EventArgs e) {
MessageBox.Show("Star!");
};
// The form
Form form = new Form();
form.Text = "Shape Button Test";
form.ClientSize = new Size(280, 100);
form.Controls.Add(ellipseButton);
form.Controls.Add(triangleButton);
form.Controls.Add(starButton);
form.ShowDialog();
}
}
Result (after clicking on the triangle button):
In winforms to change the button's image at runtime you can use something like this:
button1.Image = new Bitmap(Image.FromFile(#"Pictures\Koala.jpg"));
It should be added to event handler. For example if you want to show the image when the button is clicked you subscribe to Click event of the button and add the code into the handler method:
private void button1_Click(object sender, EventArgs e)
{
button1.Image = new Bitmap(Image.FromFile(#"Pictures\Koala.jpg"));
}
In my example,
I have a pictureBox to show, two buttons, one to control, one to be drawn.
//odd display, even draw
int count = 0;
Image storePicture;
//whenever the background image changed,store it
private void pictureBoxShow_BackgroundImageChanged(object sender, EventArgs e)
{
//you can stored to a Image array if you have series pictures to show
storePicture = pictureBoxShow.BackgroundImage;
}
private void buttonControl_Click(object sender, EventArgs e)
{
count++;
//odd show picture, even draw picture on button
if (count % 2 == 1)
pictureBoxShow.BackgroundImage = new Bitmap("shapes.JPG");
else
{
//in case you want to clear text on the button
buttonDrawn.Text = null;
//recreate the picture so that it fit the button size
buttonDrawn.Image = new Bitmap(storePicture, new Size(buttonDrawn.Width, buttonDrawn.Height));
}
}
Please remember to attach the handlers to corresponding events. ^^
Why not using PictureBox instead of Buttons.
you have just to add your task to its event/OnClick
Of course you can load any Image to any PictureBox in runtime
The code above is great, however you can click outside the circle within a square containing the circle and get the click event.
If you want to capture the click only if the user clicks inside the shape you have to set the region property with something like this
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
GraphicsPath gp = new GraphicsPath();
gp.AddEllipse(0, 0, 100, 100);
Button1.Region = new Region(gp);
}
}
I have created a function that loops a folder and retrieves each image file and draw a picturebox on the form.
Here is the function :
private void Create_Controls(string Img_path)
{
PictureBox p = new PictureBox();
p.Size = new Size(138, 100);
p.Location = new Point(6, 6);
p.BackgroundImage = Image.FromFile(Img_path);
p.BackgroundImageLayout = ImageLayout.Stretch;
this.Controls.Add(p);
}
So what i need to do is : whenever i click on any picturebox on the form , a message popup with the image file path.
So i thought about adding a custom event :
p.Click += delegate { Pop_Up(); };
AND
private void Pop_Up()
{
/* POP UP MESSAGE WITH Picturebox image file path*/
}
You need to use the property ImageLocation of the PictureBox . The property gets or sets the path or URL for the image to display in the PictureBox.
Just do the following:
p.Click += new EventHandler(Pop_Up);
...
private void Pop_Up(object sender, EventArgs e)
{
var pb = sender as PictureBox;
if(pb != null)
MessageBox.Show(pb.ImageLocation);
}
You could use Tag property for this.
something like this .
private void Create_Controls(string Img_path)
{
PictureBox p = new PictureBox();
p.Size = new Size(138, 100);
p.Location = new Point(6, 6);
p.Tag = Img_path;
p.BackgroundImage = Image.FromFile(Img_path);
p.BackgroundImageLayout = ImageLayout.Stretch;
this.Controls.Add(p);
}
private void Pop_Up()
{
MessageBox.Show(p.Tag);
}
For more on this Go here.
Then along with what HatSoft says, change your Pop_up() method like:
private void Pop_Up(object sender, EventArgs e)
{
MessageBox.Show(((PictureBox)sender).ImageLocation);
}
But maybe a bit more elegant and checking if it is indeed a PictureBox etc.
I have put in code to change the MSCharting area colour when printing.
chart.ChartAreas[o].BackColor = System.Drawing.Color.White;
chart.Printing.PrintPreview();
My quesiton is, how can I handle the color to change back to its oringinal color, eitehr after user has selected Print, or Close form the printpreview dialog,, or if the click on the dialogs "X".
In fact if I use the PrintDialog instead, how could I set background back to normal once printing has been completed or canceled?
little late but I hope it helps someone.
To MsChart print I'am using PrintDocument events. BeginPrint event for setting colors for printing, PrintPage event for print itself and EndPrint event for setting colors back before print.
Sample code:
public GraphFrm()
{
InitializeComponent();
//new PrintDocument object to reset default one
chart.Printing.PrintDocument = new System.Drawing.Printing.PrintDocument();
//set up events
chart.Printing.PrintDocument.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(PrintDocument_PrintPage);
chart.Printing.PrintDocument.BeginPrint +=new System.Drawing.Printing.PrintEventHandler(PrintDocument_BeginPrint);
chart.Printing.PrintDocument.EndPrint += new System.Drawing.Printing.PrintEventHandler(PrintDocument_EndPrint);
//default print setting like margins and landscape
chart.Printing.PrintDocument.DefaultPageSettings.Margins.Bottom = 50;
chart.Printing.PrintDocument.DefaultPageSettings.Margins.Top = 50;
chart.Printing.PrintDocument.DefaultPageSettings.Margins.Left = 50;
chart.Printing.PrintDocument.DefaultPageSettings.Margins.Right = 50;
chart.Printing.PrintDocument.DefaultPageSettings.Landscape = true;
chart.Printing.PrintDocument.DefaultPageSettings.Color = true;
...
}
public void Print()
{
//print method with show print dialog
chart.Printing.Print(true);
}
void PrintDocument_BeginPrint(object sender, System.Drawing.Printing.PrintEventArgs e)
{
//set print color
PrintChartColorSet();
}
void PrintDocument_EndPrint(object sender, System.Drawing.Printing.PrintEventArgs e)
{
//restore colors
PrintChartColorRestoreDefault();
}
void PrintDocument_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
//print chart into rectangle defined by margins
Rectangle chartPosition = new Rectangle(e.MarginBounds.X, e.MarginBounds.Y, e.MarginBounds.Width, e.MarginBounds.Height);
chart.Printing.PrintPaint(e.Graphics, chartPosition);
}
Color BackColor, BorderlineColor, CaBackColor, CaBorderColor, AxColor, LeBackColor, LeForeColor;
void PrintChartColorSet()
{
BackColor = chart.BackColor;
chart.BackColor = Color.White;
BorderlineColor = chart.BorderlineColor;
chart.BorderlineColor = Color.White;
CaBackColor = chart.ChartAreas[0].BackColor;
chart.ChartAreas[0].BackColor = Color.White;
CaBorderColor = chart.ChartAreas[0].BorderColor;
chart.ChartAreas[0].BorderColor = Color.Black;
AxColor = chart.ChartAreas[0].Axes[0].LineColor;
foreach(Axis a in chart.ChartAreas[0].Axes)
{
a.LineColor = Color.Black;
a.TitleForeColor = Color.Black;
a.MajorGrid.LineColor = Color.Black;
a.MajorTickMark.LineColor = Color.Black;
a.MinorGrid.LineColor = Color.Black;
a.MinorTickMark.LineColor = Color.Black;
a.LabelStyle.ForeColor = Color.Black;
}
LeBackColor = chart.Legends[0].BackColor;
chart.Legends[0].BackColor = Color.White;
LeForeColor = chart.Legends[0].ForeColor;
chart.Legends[0].ForeColor = Color.Black;
}
void PrintChartColorRestoreDefault()
{
chart.BackColor = BackColor;
chart.BorderlineColor = BorderlineColor;
chart.ChartAreas[0].BackColor = CaBackColor;
chart.ChartAreas[0].BorderColor = CaBorderColor;
foreach(Axis a in chart.ChartAreas[0].Axes)
{
a.LineColor = AxColor;
a.TitleForeColor = AxColor;
a.MajorGrid.LineColor = AxColor;
a.MajorTickMark.LineColor = AxColor;
a.MinorGrid.LineColor = AxColor;
a.MinorTickMark.LineColor = AxColor;
a.LabelStyle.ForeColor = AxColor;
}
chart.Legends[0].BackColor = LeBackColor;
chart.Legends[0].ForeColor = LeForeColor;
}
Unfortunatly there is no easy way since PrintPreview doesnt provide any callbacks.
You can make a copy of the chart used solely for printing with the default chart area replaced by your custom area (with custom background).
Another way is to change the BG Color, print the chart to a in-memory image using PrintPaint, restore the BG Color and show a print dialog manually for the image you just rendered.
There are more ways like hooking the newly created window but they are getting more complex and more dirty.
Good luck