How to remove PictureBoxes dynamically? - c#

I am trying to make pictureboxes fall continuously in the form.
Here is the code that I tried.
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 Rain_dropz
{
public partial class Form1 : Form
{
PictureBox[] RD = new PictureBox[500];
int ndrop = 0;
public Form1()
{
InitializeComponent();
}
public void dropIt()
{
for (int i = 0; i < ndrop; i++)
{
RD[i].Top += 10;
}
}
private void timer1_Tick(object sender, EventArgs e)
{
Random rnd = new Random();
int l = rnd.Next(1,545);
RD[ndrop] = new PictureBox();
RD[ndrop].BackColor = System.Drawing.Color.MediumBlue;
RD[ndrop].Size = new Size(5, 5);
RD[ndrop].Location = new Point(l, 0);
this.Controls.Add(RD[ndrop]);
ndrop++;
dropIt();
}
private void Form1_Load(object sender, EventArgs e)
{
timer1.Enabled = true;
timer1.Start();
}
}
}
I think it is better to delete the picture boxes which disappear from the form. How to do that?

You can remove it by removing the picturebox from form controls list.
private void timer1_Tick(object sender, EventArgs e)
{
Random rnd = new Random();
int l = rnd.Next(1,545);
RD[ndrop] = new PictureBox();
RD[ndrop].BackColor = System.Drawing.Color.MediumBlue;
RD[ndrop].Size = new Size(5, 5);
RD[ndrop].Location = new Point(l, 0);
RD[ndrop].LocationChanged += pb_LocationChanged;
this.Controls.Add(RD[ndrop]);
ndrop++;
dropIt();
}
void pb_LocationChanged(object sender, EventArgs e)
{
// FORM_LASTBOUND is the Y-Axis point after which you wanted to remove the picturebox.
if ((sender as PictureBox).Top > FORM_LASTBOUND)
{
this.Controls.Remove(sender as PictureBox);
}
}

Related

How can I display an image embedded in my program using the value from a random number generator?

I'm trying to build a Russian Roulette style program where you click a button and it randomly selects one of 25 images to display on screen but I can't seem to figure out how to call the images using the generator.
It works fine when I select an image manually, as seen in my code below, but anything else seems to return an error.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Timers;
using System.Threading.Tasks;
using System.IO;
using System.Windows.Forms;
using System.Security.Cryptography;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void label_click(object sender, EventArgs e)
{
Close();
}
int mouseX = 0, mouseY = 0;
bool mouseDown;
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
mouseDown = true;
}
private void panel1_MouseUp(object sender, MouseEventArgs e)
{
mouseDown = false;
}
private void GOBUTN_Paint(object sender, PaintEventArgs e)
{
}
//Sharing is caring: Communism goes here
private System.Windows.Forms.Timer timtim;
int rand0;
PictureBox Rooskie = new PictureBox();
Label test = new Label();
Random rando = new Random();
List<int> duplicheck = new List<int>();
private void boopthesnoot(object sender, EventArgs e)
{
dingding:
//Hell yeah, random numbers here
rand0 = rando.Next(1, 26);
/*string combowombo = string.Join(", ", duplicheck.ToArray());
test.Text = combowombo;
test.Font = new Font("Calibri", 20);
Controls.Add(test);
test.Location = new Point(0, 200);
test.Height = 1000;
test.Width = 1000;*/
if(duplicheck.Contains(rand0))
{
goto dingding;
}
else
{
GOBUTTON.Hide();
pictureBox1.Hide();
pictureBox2.Hide();
//Fuckin image code goes here my dood
Rooskie.Width = 1160;
Rooskie.Height = 620;
Bitmap image = new Bitmap(WindowsFormsApp1.Properties.Resources._1);
Rooskie.Dock = DockStyle.Fill;
Rooskie.Image = (Image)image;
Controls.Add(Rooskie);
Rooskie.SizeMode = PictureBoxSizeMode.CenterImage;
//Aww shit, it's that timer time
timtim = new System.Windows.Forms.Timer();
timtim.Tick += new EventHandler(clockfinish);
timtim.Interval = 3000;
timtim.Start();
duplicheck.Add(rand0);
if (duplicheck.Count == 25)
{
duplicheck = new List<int>();
}
}
}
private void clockfinish(object sender, EventArgs e)
{
//CEASE THE TIMER AND GIVE ME BACK MY BUTTON
Rooskie.Image = null;
timtim.Stop();
GOBUTTON.Show();
pictureBox1.Show();
pictureBox2.Show();
}
The expected result is when the user presses the button it calls up the image without having to load it from a folder.

How can I delete all Panels from my calendar?

I'm programming an calendar with C# right now.
If i call my calendar, it creates as much panels as the current month has days. But if I want to increase the current month by one, the panels from the current month are stilt there.
So i have to delete all my panels as soon as I change the month.
But how can i do it in this case ?
Thanks for the help.
Code eplain:
First I call the createPanel method, to create panels for the current month.
Next if I click the MonthAdd method, I want to delete all my created panels.
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.Globalization;
namespace Einteilungs_Plan
{
public partial class Kalender : Form
{
public DateTime TodayDate { get; set; }
int counting = 0;
public Kalender()
{
InitializeComponent();
//Kalenderwochen initialisieren
monat(counting);
createPanel(true);
}
public string monat(int adding)
{
string monat = DateTime.Now.AddMonths(adding).ToString("MMMM");
tbMonat.Text = monat;
return monat;
}
private void btnAddMonth_Click(object sender, EventArgs e)
{
counting++;
if(counting < 12)
{
monat(counting);
switch (counting)
{
case 0:
int number = 10;
break;
case 1:
break;
default:
break;
}
}
else
{
counting--;
}
}
private void btnRemoveMonth_Click(object sender, EventArgs e)
{
counting--;
if (counting > -1)
{
monat(counting);
}
else
{
counting++;
}
}
public void createPanel(bool remove)
{
var numDays = DateTime.DaysInMonth(DateTime.Today.Year, DateTime.Today.Month);
int locationX = 12;
int locationY = 74;
for (int i = 0; i <= numDays; i++)
{
//Create Panel
Panel test = new Panel();
//Fill Panel
test.Name = "panel" + i;
test.Width = 200;
test.Height = 100;
test.BackColor = Color.White;
test.Location = new System.Drawing.Point(locationX, locationY);
this.Controls.Add(test);
test.Show();
if(i == 6 || i == 13 || i == 20 || i == 28)
{
locationY += 106;
locationX = -194;
}
locationX += 206;
}
}
public void Kalender_Shown(object sender, EventArgs e)
{
}
private void Kalender_Load(object sender, EventArgs e)
{
}
private void btnNeuerEintrag_Click(object sender, EventArgs e)
{
Formular formular = new Formular();
formular.Show();
formular.Focus();
}
private void btnHinzufügen_Click(object sender, EventArgs e)
{
Formular formular = new Formular();
formular.Show();
formular.Focus();
}
}
}
...
for (int i = 0; i <= numDays; i++)
{
//Create Panel
test[i] = new Panel();
}
...
and then
this.Control.Remove(test[i]);
I'm not sure if I undestood you well but first simple solutiona that comes into my mind is that while creating panels you can keep them in some List for example and before generating new month you can call
foreach (var p in panels)
this.Controls.Remove(p);

How to generate random integers in a text box in C#

How do I randomly generate integer values in a text box for every one second till I click on a button.
I came up with following code (Clicking on Button 1 should generate random integers for every 1 second in textBox1 till Button2 is clicked) and its not working (Output is empty text box).
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.Timers;
namespace WindowsFormsApplication5
{
public partial class Form1 : Form
{
bool buttonclicked = false;
System.Timers.Timer myTimer;
System.Random r = new System.Random();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
while (buttonclicked == false)
{
myTimer = new System.Timers.Timer();
myTimer.Elapsed += new ElapsedEventHandler(rnd);
myTimer.Interval = 1000;
myTimer.Start();
}
}
public void rnd(Object sender, EventArgs e)
{
textBox1.Text = r.Next(0, 1000).ToString();
}
private void button2_Click(object sender, EventArgs e)
{
buttonclicked = true;
myTimer.Stop();
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
}
}
Your while(buttonclicked == false) will create an infinite loop once you click the button.You can just do
private void button1_Click_1(object sender, EventArgs e)
{
myTimer = new System.Timers.Timer();
myTimer.Elapsed += new System.Timers.ElapsedEventHandler(rnd);
myTimer.Interval = 1000;
myTimer.Start();
}
private void button2_Click_1(object sender, EventArgs e)
{
myTimer.Stop();
}
and you need to make a safe thread call to the textbox by doing :
delegate void SetTextCallback(string text);
private void SetText(string text)
{
if (this.textBox1.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
this.textBox1.Text = text;
}
}
And to set the text just use SetText(r.Next(0 ,1000).ToString());
Looks like it is because you are using a while loop instead of an if block. Your condition should look like this:
if( buttonclicked == false)
{
....
}
I think you were right to a loop - but not the timer.
No need to declare the System.Random at the class level either - unless you're using it elsewhere.
Using a for loop.
private void button1_Click_1(object sender, EventArgs e)
{
var r = new System.Random();
for (var i = 0; i < 1000; i++)
{
textBox1.Text = r.Next(0, 1000).ToString();
}
}
Using a while loop.
private void button1_Click_1(object sender, EventArgs e)
{
var r = new System.Random();
var i = 0;
while (i < 1000)
{
textBox1.Text = r.Next(0, 1000).ToString();
i++;
}
}
If you really want to add a new number each second, you could use async and await (to stop UI blocking) and add a System.Threading.Thread.Sleep(1000);.
Or even Task based would be better than a Timer (in my opinion). It's good to understand how Tasks work.
A Timer is okay for this scenario - but in real applications they can get messy, especially with multiple timers.
Here is an example of how the above would work using Tasks.
private void button1_Click(object sender, EventArgs e)
{
var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
Task.Factory.StartNew(() => AddRandomNumbers(uiScheduler));
}
private async Task AddRandomNumbers(TaskScheduler uiScheduler)
{
var r = new Random();
for (int i = 0; i < 1000; i++)
{
await Task.Factory.StartNew(
() => textBox1.Text = r.Next(0, 1000).ToString(),
CancellationToken.None,
TaskCreationOptions.None,
uiScheduler);
Thread.Sleep(1000);
}
}

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.

Buttons added dynamically to form don’t appear

I'm trying to create 4 buttons on my form when I click on button1, but the buttons don’t show up. Why not?
private void button1_Click(object sender, EventArgs e)
{
Button[] b = new Button[4];
for (int i=0; i < 4; i++)
{
b[i] = new Button();
b[i].Name = "button" + i;
b[i].Location = new Point(43, 39 + 10 * i);
b[i].Size = new Size(158, 48);
}
}
You have only created them, but you also need to add them to your form with: this.Controls.Add(b[i]);
private void button1_Click(object sender, EventArgs e)
{
Button[] b = new Button[4];
for (int i=0; i < 4; i++)
{
b[i] = new Button();
b[i].Name = "button" + i;
b[i].Location = new Point(43, 39 + 10 * i);
b[i].Size = new Size(158, 48);
this.Controls.Add(b[i]);
}
}
All you do is create an array of buttons, and assign buttons at indices. Your form knows nothing of these buttons, they could be an array of integers or anything for all that matters at this point. You will need to put them in the form's container:
Controls.Add(b[i]);
Now your form will take ownership of them, managing disposal when the container is disposed.
Try this:
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 winFormButtons
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Button[] b = new Button[4];
for (int i = 0; i < 4; i++)
{
b[i] = new Button();
b[i].Name = "button" + i;
b[i].Location = new Point(43, 39 + 10 * i);
b[i].Size = new Size(158, 48);
b[i].Click += new EventHandler(OnClick);
this.Controls.Add(b[i]);
}
}
public void OnClick(object sender, EventArgs e)
{
MessageBox.Show("Hello Handler:" + ((Button)sender).Name);
}
}
}
Create a Panel on your form. and add this line in your code
panel1.Controls.Add(b[i])

Categories

Resources