I try to put text from 0 to 11 on 12 pictureboxes have a ball image, but get the text 11 on all.
How can I get the text on the balls from 0 to 11 ?
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 wfballs2
{
public partial class Form1 : Form
{
String s;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
PictureBox[] Shapes = new PictureBox[12];
for (int i = 0; i < 12; i++)
{
s = Convert.ToString(i);
Shapes[i] = new PictureBox();
Shapes[i].Name = "ball" + i.ToString();
Shapes[i].Location = new Point(10 + 45 * i, 300);
Shapes[i].Size = new Size(40, 40);
Shapes[i].Image = Image.FromFile(# "C:\Users\Eiko\Desktop\ball\ball.jpg");
Shapes[i].SizeMode = PictureBoxSizeMode.CenterImage;
Shapes[i].Visible = true;
this.Controls.Add(Shapes[i]);
Shapes[i].Paint += new PaintEventHandler((sender2, e2) =>
{
e2.Graphics.DrawString(s, Font, Brushes.Black, 10, 13);
});
}
}
}
}
The variable s is an instance in your form, so its value is shared by the form and all the shapes you create.
Everytime one of your shape is painted, this code:
e2.Graphics.DrawString(s, Font, Brushes.Black, 10, 13);
will run. That s is an instance variable of your Form. It will show for all shapes the last value that it was set to. In your case that happens in the last iteration of your for loop, hence the 11.
To fix this you have to capture the loop variable in a local variable before the anonymous eventhandler and then use that local var to do the Convert.ToString(val) in the event handler, like so:
var val = i; // capture variable
Shapes[i].Paint += new PaintEventHandler((sender2, e2) =>
{
// use captured variable here
e2.Graphics.DrawString(Convert.ToString(val), Font, Brushes.Black, 10, 13);
});
This will generate the string with the local variable based on val.
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace wfballs2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
int k = 0;
PictureBox[] Shapes = new PictureBox[12];
for (int i = 0; i < 12; i++)
{
Shapes[i] = new PictureBox();
Shapes[i].Name = "ball" + i.ToString();
Shapes[i].Location = new Point(10 + 45 * i, 300);
Shapes[i].Size = new Size(40, 40);
Shapes[i].Image = Image.FromFile(# "C:\Users\Eiko\Desktop\ball\ball.jpg");
Shapes[i].SizeMode = PictureBoxSizeMode.CenterImage;
Shapes[i].Visible = true;
this.Controls.Add(Shapes[i]);
Shapes[i].Paint += new PaintEventHandler((sender2, e2) =>
{
e2.Graphics.DrawString(k.ToString(), Font, Brushes.Black, 10, 13);
k++;
});
}
}
}
}
Related
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MyTest
{
public partial class Form1 : Form
{
private int x, y;
private int gap = 0;
private int startingY = 150;
private GroupBox lastGB = null;
public Form1()
{
InitializeComponent();
GroupBox gb = new GroupBox();
gb.Location = new Point(100, (lastGB == null ? startingY : lastGB.Bounds.Bottom));
gb.Size = new Size(1220, 400);
gb.BackColor = SystemColors.Window;
gb.Text = "";
gb.Font = new Font("Colonna MT", 12);
this.Controls.Add(gb);
}
It's creating a small line on the top of the groupbox and I don't want this line to show.
And I want to write some text on it in the middle of it.
How can I make it just complete white ? And how to write some text in the middle on the groupbox ?
The main idea is to create over the form a white sheet or box with text inside that's it.
It looks like your intention is to put subsequent boxes just below the last box. As mentioned, a Label would probably be best. I'd also move that code to a method you can call over and over to keep from repeating code elsewhere. You could pass a message to display in the Label. Also, don't forget to update the reference to the "last box" when ever you create a new one:
public partial class Form1 : Form
{
private int x, y;
private int gap = 0;
private int startingY = 150;
private Label lastLbl = null;
public Form1()
{
InitializeComponent();
AddLabel("Hello World");
}
private void button1_Click(object sender, EventArgs e)
{
AddLabel(DateTime.Now.ToString());
}
private void AddLabel(String msg)
{
Label lbl = new Label();
lbl.Location = new Point(100, (lastLbl == null ? startingY : lastLbl.Bounds.Bottom));
lbl.Size = new Size(1220, 400);
lbl.BackColor = Color.White;
lbl.Text = msg;
lbl.TextAlign = ContentAlignment.MiddleCenter;
lbl.Font = new Font("Colonna MT", 12);
this.Controls.Add(lbl);
lastLbl = lbl;
}
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
Today I've tried Visual Studio + WinForms (I've been using Xamarin)
I dont use designer, just create empty project and link needed libraries.
So, my timer doesn't work properly, it ticks only in minimized form.
App.cs
using System;
using System.Windows.Forms;
namespace Line
{
class App
{
[STAThread]
public static void Main()
{
Application.Run(new Window());
}
}
}
Window.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing;
using System.ComponentModel;
namespace Line
{
class Window : Form
{
Timer timer;
PictureBox pictureBox;
Bitmap bmp;
public struct Circle
{
public PointF position;
public SizeF size;
};
List<Circle> circles;
public Window()
{
this.Text = "Line";
this.Size = SizeFromClientSize(new Size(640, 480));
pictureBox = new PictureBox();
pictureBox.Dock = DockStyle.Fill;
pictureBox.BackColor = Color.White;
pictureBox.Paint += new PaintEventHandler(pictureBox_Paint);
this.Controls.Add(pictureBox);
this.Load += new EventHandler(Window_Load);
this.Resize += new EventHandler(Window_Resize);
circles = new List<Circle>();
timer = new Timer();
timer.Interval = 15;
timer.Enabled = true;
timer.Tick += new EventHandler(timer_Tick);
}
private void pictureBox_Paint(object sender, PaintEventArgs e)
{
Graphics g = Graphics.FromImage(bmp);
g.Clear(Color.Black);
foreach (Circle c in circles)
{
g.DrawEllipse(Pens.White, new RectangleF(c.position, c.size));
}
pictureBox.Image = bmp;
}
private void timer_Tick(object sender, EventArgs e)
{
Circle c;
Console.WriteLine("Works");
for (int i = 0; i < circles.Count; i++)
{
c = circles[i];
c.size.Width = (c.size.Width > 200) ? 100 : c.size.Width + 1;
circles[i] = c;
}
pictureBox.Invalidate();
}
private void Window_Load(object sender, EventArgs e)
{
bmp = new Bitmap(this.Width, this.Height);
circles.Add(new Circle());
Circle c = circles[0];
c.position = new PointF(100, 100);
c.size = new SizeF(100, 100);
circles[0] = c;
}
private void Window_Resize(object sender, EventArgs e)
{
bmp = new Bitmap(this.Width, this.Height);
pictureBox.Invalidate();
}
}
}
Same code worked fine in Xamarin.
1) in timer_Tick remove line: pictureBox.Invalidate();
2) cut code from pictureBox_Paint and paste at the end of timer_Tick
3) fix variable name collision c
I am new to c# and I'm trying to understand z-index concept. So far I have a simple form created using ConsoleApplication project in visual studio. There are 3 cs files. Here's the code:
In Algorithm.cs (inherited from UI.cs):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing;
public class Algorithm : UI
{
private Timer refresh = new Timer();
//Ball settings
private const int offset = 25;
private const int rate = 200;
private int ball_bounding_box_x_coord;
private int ball_bounding_box_y_coord;
private int x;
private int y;
private const int width = 50;
private const int height = 50;
Brush brush = new SolidBrush(Color.Blue);
public bool isStartClicked = false;
Button test = new Button();
public Algorithm()
{
test.Text = "test";
test.Location = new Point(0, 800);
test.Size = new Size(100, 50);
test.TabIndex = 0;
bottom.Controls.Add(test);
test.BringToFront();
ball_bounding_box_x_coord = middle.Size.Width / 2 - width / 2;
ball_bounding_box_y_coord = middle.Size.Height / 2 - height / 2;
middle.Paint += new PaintEventHandler(Draw);
start.Click += new EventHandler(Start);
}
private void Calculate()
{
Graphics g = middle.CreateGraphics();
//g.FillEllipse(brush, )
}
private void Draw(object sender, PaintEventArgs e)
{
e.Graphics.FillEllipse(brush, ball_bounding_box_x_coord , ball_bounding_box_y_coord , width, height);
}
public void Start(object sender, EventArgs e)
{
MessageBox.Show("Button clicked");
}
}
In UI.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing;
public class UI : Form
{
//Window settings
private const int WINDOW_WIDTH = 1600;
private const int WINDOW_HEIGHT = 900;
private Panel top = new Panel();
public Panel middle = new Panel();
public Panel bottom = new Panel();
private Label title = new Label();
//Text box for degree input
private Label degree_input_label = new Label();
private TextBox degree_input = new TextBox();
public double input;
//Label to display x and y coordinates of the ball
public Label ball_x_coord = new Label();
public Label ball_y_coord = new Label();
//Buttons
public Button start = new Button();
private Button quit = new Button();
public UI()
{
//total height of 3 areas != window_height????????????????
//Setup window form
this.Width = WINDOW_WIDTH;
this.Height = WINDOW_HEIGHT;
this.Text = "Project 2";
//Add a badass title
title.Text = "Designed by Me";
title.AutoSize = true;
title.Location = new Point(600, 20);
title.Font = new Font(title.Font.Name, 24, FontStyle.Bold);
title.BackColor = Color.Red;
Controls.Add(title);
top.Location = new Point(0, 0);
top.Size = new Size(WINDOW_WIDTH, 80);
top.BackColor = Color.Red;
middle.Location = new Point(0, top.Location.Y + top.Size.Height);
middle.Size = new Size(WINDOW_WIDTH, 680);
middle.BackColor = Color.Cyan;
bottom.Location = new Point(0, top.Location.Y + top.Size.Height + middle.Size.Height);
bottom.Size = new Size(WINDOW_WIDTH, WINDOW_HEIGHT - top.Height - middle.Height);
bottom.BackColor = Color.Green;
degree_input_label.Text = "Enter a degree:";
degree_input_label.Location = new Point(100, bottom.Location.Y + 20);
degree_input_label.AutoSize = true;
Controls.Add(degree_input_label);
degree_input.Size = new Size(50, 50);
degree_input.Location = new Point(200, bottom.Location.Y + 20);
degree_input.Leave += new EventHandler(TextChange);
degree_input.TabIndex = 2;
Controls.Add(degree_input);
ball_x_coord.Text = "Ball X Coord";
ball_x_coord.Location = new Point(400, bottom.Location.Y + 20);
ball_x_coord.AutoSize = true;
Controls.Add(ball_x_coord);
ball_y_coord.Text = "Ball y coord";
ball_y_coord.Location = new Point(500, bottom.Location.Y + 20);
ball_y_coord.AutoSize = true;
Controls.Add(ball_y_coord);
start.Text = "Start";
start.Location = new Point(1100, bottom.Location.Y + 20);
start.Size = new Size(100, 50);
start.TabIndex = 1;
Controls.Add(start);
quit.Text = "Quit";
quit.Location = new Point(1400, bottom.Location.Y + 20);
quit.Size = new Size(100, 50);
quit.Click += new EventHandler(Quit);
Controls.Add(quit);
//ADD BACKGROUND CONTROLS
Controls.Add(top);
Controls.Add(middle);
Controls.Add(bottom);
}//end constructor
private void TextChange(object sender, EventArgs e)
{
if(degree_input.TextLength <= 0)
{
degree_input.Text = "0";
MessageBox.Show("Please enter a degree");
degree_input.Focus();
}else
{
input = double.Parse(degree_input.Text);
//MessageBox.Show(input.ToString());
}
}
void Quit(object sender, EventArgs e)
{
Application.Exit();
}
}
In Main.cs:
class Program
{
static void Main(string[] args)
{
Algorithm al = new Algorithm();
UI a = new UI();
//Application.Run(a);
Application.Run(al);
}
}
The problem I'm having is that the test button is not visible. If i remove the bottom panel and add the test button directly on the form then it is visible. Why doesn't it appear on the bottom panel even after I used bringtofront() ?
Why doesn't it appear on the bottom panel even after I used bringtofront() ?
Because you've placed it outside the visual boundary of the panel:
test.Location = new Point(0, 800);
That sets the position of the button to a horizontal offset of 0 and a vertical offset of 800. The bottom panel is only 140 pixels high, so 800 is well below the bottom of the visible area.
It's not really clear what you meant to do. Given that the window width is 1600 pixels and 800 is half that, maybe you just transposed the X and Y coordinates and meant this instead:
test.Location = new Point(800, 0);
That would place the button in the middle of the panel, aligned to the top.
Other than that, I can't imagine why if you wanted the button to be visible, you would hard-code a location for it that is not in a visible area.
I have a little problem of mine to solve. I have a button which has an image background.I tried to color the whole button but the image can not be seen after coloring the whole button. How can I edit this "imagebutton" like in this example? http://i.stack.imgur.com/XaQQQ.png
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 bura
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button2_Click(object sender, EventArgs e)
{
if (button2.BackgroundImage != null)
{
button2.BackgroundImage = null;
button2.BackColor = Color.Black;
}
else {
button2.BackgroundImageLayout = ImageLayout.Stretch;
button2.BackgroundImage = Image.FromFile("C:\\Users\\rati\\Desktop\\ks.png");
}
}
private void button3_Click(object sender, EventArgs e)
{
button2.BackgroundImageLayout = ImageLayout.Stretch;
button2.BackgroundImage = Image.FromFile("C:\\Users\\rati\\Desktop\\ks.png");
}
}
}
This
Just made a button by using the designer with the following code:
this.button1.BackColor = System.Drawing.Color.DodgerBlue;
this.button1.BackgroundImage = global::WindowsFormsApplication.Properties.Resources.ChargeImage;
this.button1.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
this.button1.Image = global::WindowsFormsApplication.Properties.Resources.DatabaseImage;
this.button1.Location = new System.Drawing.Point(12, 12);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(264, 160);
this.button1.TabIndex = 0;
this.button1.UseVisualStyleBackColor = false;
And that is the result:
So what is your problem?
You can edit your pictures with a method like this:
private static void DrawLinesOnBitmap(Bitmap bmp)
{
using (var p = new Pen(Color.Black, 5))
{
using (var g = Graphics.FromImage(bmp))
{
g.DrawLine(p, 0, 0, bmp.Width, bmp.Height);
}
}
}
This method adds a line from the left top corner to the right bottom corner. Just draw some more lines and you should get your wanted result.
I am stuck at trying to call a procedure and use some parameters in a new thread in C#. There 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.Windows.Forms;
using System.Threading;
namespace Random_colored_rectangles
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Thread th;
Random rand;
System.Drawing.Color[] colors = new System.Drawing.Color[5] {Color.Orange, Color.Red, Color.Pink, Color.Black, Color.Gold };
private void DrawColor(Color color)
{
for (int i = 0; i < 100; i++)
{
DrawRectangle(color, 3 , rand.Next(0, this.Width), rand.Next(0, this.Height), 10, 10);
Thread.Sleep(100);
}
MessageBox.Show(color + " done");
}
private void DrawRectangle(Color barva, float width, int pos_x, int pos_y, int size_x, int size_y)
{
Pen myPen = new Pen(barva, width);
Graphics formGraphics;
formGraphics = plocha.CreateGraphics();
formGraphics.DrawRectangle(myPen, new Rectangle(pos_x, pos_y, size_x, size_y));
myPen.Dispose();
formGraphics.Dispose();
}
private void Form1_Load(object sender, EventArgs e)
{
rand = new Random();
}
private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.R)
{
th = new Thread(DrawColor);
th.Name = Convert.ToString(threadCount);
threadList.Add(th);
threadCount = threadCount + 1;
th.Start(colors[rand.Next(0, colors.Length)]);
}
}
}
}
This code should (after pressing R) make 100 random colored rectangles (the color is chosen from an array of few colors). But, I am unable to make my thread start the procedure DrawColor with a parameter of the random color select.
Can you please help me?
You could do it by using a Task.
Color theColorToPass = someColor;
Task.Factory.StartNew(color => {
DrawColor(color);
}, theColorToPass);
You could aswell access the array directly from within the Task though. I see no point in passing it to the Thread.
Using the advice of those more familiar with the do's and don'ts of C# (that is not me trying to sound mean or anything), I have devised a way to accomplish what you want without the need of CreateGraphics() or Thread.Sleep(). Unfortunately, this throws an OutOfMemoryException when it hits e.Graphics.DrawRectangle(penToUse, rectanglesToUse[0]);. What does that mean?
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace Colors
{
public partial class Form1 : Form
{
Timer timer = new Timer { Interval = 100 };
Random rand = new Random();
Color[] colors = new Color[5]
{
Color.Black,
Color.Blue,
Color.Green,
Color.Purple,
Color.Red
};
List<Pen> usedPens = new List<Pen>();
List<Rectangle> usedRectangles = new List<Rectangle>();
Pen penToUse;
List<Rectangle> rectanglesToUse = new List<Rectangle>();
public Form1()
{
InitializeComponent();
}
protected override void OnKeyPress(KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Enter)
{
penToUse = new Pen(GetRandomColor(), 3);
rectanglesToUse.Clear();
for (int i = 0; i < 100; i++)
rectanglesToUse.Add(GetRandomRectangle());
this.Refresh();
}
}
private Color GetRandomColor()
{
return colors[rand.Next(0, colors.Length)];
}
private Rectangle GetRandomRectangle()
{
return new Rectangle(rand.Next(0, Width), rand.Next(0, Height), 10, 10);
}
protected override void OnPaint(PaintEventArgs e)
{
for (int i = 0; i < usedRectangles.Count; i++)
e.Graphics.DrawRectangle(usedPens[i % 100], usedRectangles[i]);
timer.Tick += delegate
{
if (rectanglesToUse.Count > 0)
{
e.Graphics.DrawRectangle(penToUse, rectanglesToUse[0]);
usedRectangles.Add(rectanglesToUse[0]);
rectanglesToUse.RemoveAt(0);
}
else
{
usedPens.Add(penToUse);
timer.Stop();
}
};
timer.Start();
}
}
}