Im creating a transition for my form in Visual Studio,
i'm coding a slide effect for the width but it ends up to slow
is there anyway to make it more faster?
btw here is the code :
`int check = 0;
private void button1_Click(object sender, EventArgs e)
{
this.button1.Text = "Hide";
if (check == 0)
{
for (int i = 350; i <= 824; ++i)
{
this.Size = new Size(i, 507);
Thread.Sleep(10);
this.CenterToScreen();
}
check = 1;
}
else if (check == 1)
{
this.button1.Text = "Key";
for (int i = 824; i >= 351; i--)
{
this.Size = new Size(i, 507);
Thread.Sleep(5);
this.CenterToScreen();
}
check = 0;
}
}
By using your existing code, you can tune it for the sake of speed like;
private int check = 0;
private void button1_Click(object sender, EventArgs e)
{
this.button1.Text = "Hide";
if (check == 0)
{
for (int i = 350; i <= 824; i += 2)
{
this.Size = new Size(i, 507);
Thread.Sleep(1);
this.CenterToScreen();
}
check = 1;
}
else if (check == 1)
{
this.button1.Text = "Key";
for (int i = 824; i >= 351; i -= 2)
{
this.Size = new Size(i, 507);
Thread.Sleep(1);
this.CenterToScreen();
}
check = 0;
}
}
You can change Thread.Sleep lines as above and increase or decrease the loop variables for faster an animation.
Related
I'm working on a multimedia assignment and I found that the Dr is using this.load in the code so...
I don't understand why do we need this event handler as I think we can work without it.
I don't get why do I need such a ready made function and how it would be useful in multimedia programming or gaming programming.
This is my code :
namespace changecolors
{
public class Actor
{
public int X, Y, W, H;
public Color cl;
}
public partial class Form1 : Form
{
List<Actor> L = new List<Actor>();
int pos = -1;
public Form1()
{
this.WindowState = FormWindowState.Maximized;
this.Load += new EventHandler(Form1_Load);
this.KeyDown += new KeyEventHandler(Form1_KeyDown);
this.MouseDown += new MouseEventHandler(Form1_MouseDown);
}
void Form1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
pos = -1;
for (int i = 0; i < L.Count; i++)
{
if (e.X >= L[i].X
&& e.X <= L[i].X + L[i].W
&& e.Y >=L[i].Y
&& e.Y <= L[i].Y + L[i].H)
{
pos = i;
}
}
}
else
{
if (pos > -1)
{
L[pos].Y += 10;
}
}
DrawScene();
}
void Form1_KeyDown(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.Space:
DrawScene();
break;
}
}
void Form1_Load(object sender, EventArgs e)
{
int V = 100;
Color[] z = { Color.DarkGray, Color.Red, Color.Blue };
for (int i = 0; i < 3; i++)
{
Actor pnn = new Actor();
pnn.X = V;
pnn.Y = 200;
pnn.W = 70;
pnn.H = 170;
pnn.cl = z[i];
V += pnn.W;
L.Add(pnn);
}
}
void DrawScene()
{
Graphics g = this.CreateGraphics();
g.Clear(Color.MistyRose);
for (int i = 0; i < L.Count; i++)
{
SolidBrush br = new SolidBrush(L[i].cl);
g.FillRectangle(br,
L[i].X, L[i].Y,
L[i].W, L[i].H);
}
}
}
}
The problem is the label gets displayed before the progress-bar is completed. How do I make the label display only after the progress-bar is fully complete?
I tried changing the max values to a higher number but it didn't work.
public partial class dload : Form
{
public dload()
{
InitializeComponent();
}
private void dload_Load(object sender, EventArgs e)
{
label1.Visible = false;
}
private void button1_Click(object sender, EventArgs e)
{
int i = 0;
progressBar1.Minimum = 0;
progressBar1.Maximum = 5000;
for (i = 0; i <= 5000; i++)
{
progressBar1.Value = i;
if (i == 5000)
{
label1.Visible = true;
}
}
}
}
Actually, Your code run very vast, it is about less than a second to set value from 0% to 100% ! But
ProgressBar has two styles for displaying the current status (Classic and Continues).
In Continues mode if the progress value went to 100% from 0% the control will show an animation, which is not display the real and accurate progress. You can set a delay via Thread.Sleep() and show your label immediately after the for loop to find out to what i happening !
The Below code will work:
private void button1_Click(object sender, EventArgs e)
{
int i = 0;
progressBar1.Minimum = 0;
progressBar1.Maximum = 5000;
for (i = 0; i <= 5000; i++)
{
Thread.Sleep(1);
progressBar1.Value = i;
}
label1.Visible = true;
}
This is an animation problem. A "hack" around it is to actually decrease the progress value by 1:
progressBar1.Minimum = 0;
progressBar1.Maximum = 5000;
for (int i = 0; i < progressBar1.Maximum; i++) {
progressBar1.Value = i;
progressBar1.Value = Math.Max(i - 1, progressBar1.Minimum);
}
label1.Visible = true;
use progressBar1.Refresh:
public partial class dload : Form
{
public dload()
{
InitializeComponent();
}
private void dload_Load(object sender, EventArgs e)
{
label1.Visible = false;
}
private void button1_Click(object sender, EventArgs e)
{
int i = 0;
progressBar1.Minimum = 0;
progressBar1.Maximum = 5000;
for (i = 0; i <= 5000; i++)
{
progressBar1.Value = i;
progressBar1.Refresh();
if (i == 5000)
{
label1.Visible = true;
}
}
}
I'm trying to make a simple countdown timer program. There are two timer objects. Once timer1 runs out of time, it stops and timer2 starts counting down. When timer2 runs out of time, timer1 starts again and so on. Here is my code:
private void timer1_Tick(object sender, EventArgs e)
{
milli1--;
if(milli1 == -1)
{
sec1--;
milli1 = 59;
if (sec1 == -1)
{
min1--;
sec1 = 59;
if (min1 == -1)
{
min1 = 0;
sec1 = 0;
milli1 = 0;
Console.WriteLine("Timer1 stops!");
timer1.Stop();
timer2.Start();
}
}
}
//updates displayed time
}
However, when timer1 stops, timer2 doesn't seem to start. Somehow, timer1 continues ticking and continuously outputs "Timer1 Stops!" to console. How do I fix this?
EDIT: Here is my timer2_Tick():
private void timer2_Tick(object sender, EventArgs e)
{
milli2--;
if (milli2 == -1)
{
sec2--;
milli2 = 59;
if (sec2 == -1)
{
min2--;
sec2 = 59;
if (min2 == -1)
{
min2 = 0;
sec2 = 0;
milli2 = 0;
timer2.Stop();
timer1.Start();
}
}
}
//updates displayed time
}
EDIT 2: Two timers with same interval is a trivial matter. My code also doesn't work when the timers have different intervals.
I am not sure why you want to use a Timer for a console application as it is not event driven as a Windows.Forms.Timer is. You may be using a Threading timer but your code won’t work as it is using this timer. So below I created a windows form application and set the output type to the console and used the timers as you described and it works as expected. I do not think you can use a timer the way you are in a console application. Again this code makes little sense as ONE timer will do the same thing. If you must use a console application then you may want to check the following post: How do you add a timer to a C# console application
int milli1 = 0;
int milli2 = 0;
int sec1 = 0;
int min1 = 0;
int sec2 = 0;
int min2 = 0;
public Form1() {
InitializeComponent();
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e) {
Console.WriteLine("Timer1 tick!");
milli1--;
if (milli1 == -1) {
sec1--;
milli1 = 59;
if (sec1 == -1) {
min1--;
sec1 = 59;
if (min1 == -1) {
min1 = 0;
sec1 = 0;
milli1 = 0;
//Console.WriteLine("Timer1 stops!");
timer1.Stop();
timer2.Start();
}
}
}
//updates displayed time
}
private void timer2_Tick(object sender, EventArgs e) {
Console.WriteLine("Timer2 tick!");
milli2--;
if (milli2 == -1) {
sec2--;
milli2 = 59;
if (sec2 == -1) {
min2--;
sec2 = 59;
if (min2 == -1) {
min2 = 0;
sec2 = 0;
milli2 = 0;
timer2.Stop();
timer1.Start();
}
}
}
//updates displayed time
}
}
In Form1 im creating 8 pictureBoxes in the constructor:
pbs = new PictureBox[8];
progressbars = new ProgressBar[8];
for (int i = 0; i < pbs.Length; i++)
{
progressbars[i] = new ProgressBar();
progressbars[i].Size = new Size(100, 10);
progressbars[i].Margin = new Padding(0, 0, 0, 70);
progressbars[i].Dock = DockStyle.Top;
pbs[i] = new PictureBox();
pbs[i].MouseEnter += globalPbsMouseEnterEvent;
pbs[i].MouseLeave += globalPbsMouseLeaveEvent;
pbs[i].Tag = "PB" + i.ToString();
pbs[i].Size = new Size(100, 100);
pbs[i].Margin = new Padding(0, 0, 0, 60);
pbs[i].Dock = DockStyle.Top;
pbs[i].SizeMode = PictureBoxSizeMode.StretchImage;
Panel p = i < 4 ? panel1 : panel2;
p.Controls.Add(pbs[i]);
p.Controls.Add(progressbars[i]);
pbs[i].BringToFront();
progressbars[i].BringToFront();
}
In timer1 tick event i assign the images to a pictureBox in a loop so it will look like animation.
private void timer1_Tick(object sender, EventArgs e)
{
try
{
for (int i = 0; i < file_array.Length; i++)
{
}
if (leave == true)
{
pb.Load(file_array[file_indxs]);
}
else
{
pbs[0].Load(file_array[file_indxs]);
}
file_indxs = file_indxs + 1;
if (file_indxs >= file_array.Length)
{
file_indxs = 0;
}
}
catch
{
timer1.Enabled = false;
}
}
And file_array is string[] im creating it by getting the files from the directories:
private void getfiles()
{
List<FileInfo> fileList = new List<FileInfo>();
for (int i = 0; i < BackgroundWorkerConfiguration.urlsDirectories.Count; i++)
{
System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(BackgroundWorkerConfiguration.urlsDirectories[i]);
fileList.AddRange(di.GetFiles("*.*", System.IO.SearchOption.AllDirectories)
.Where(x => x.Length > 0).Select(y => y));
}
var file_array = fileList.OrderBy(x => x.CreationTime)
.GroupBy(x => x.DirectoryName)
.Select(g => g.Select(x => x.FullName).ToList())
.ToArray();
timer1.Enabled = true;
}
Now in the timer tick event i loop over the file_array and assign all the images to the first pictureBox: pbs[0]
But now the variable file_array is not the same. Before it was just string[] with many files inside of images.
Now file_array is like this:
in index 0 i have 48 files.
in index 1 index 2 index and index 4 there are 61 files in each index.
I want in the timer tick event to assign each index of file to another pictureBox.
So index 0 in the file_array all the 48 files should be assign to pbs[0]
Index 1 the files should be assign to pbs[1]...
And so on untill index 4 to assign to pbs[4]
But i dont want to write as i did before pbs[0].Load...
I want that it will automatic load the images from file_array indexs to the pictureBoxes.
The first files in index 0 to the first pictureBox and so on...
EDIT**
public void globalPbsMouseEnterEvent(object sender, System.EventArgs e)
{
PictureBox p = sender as PictureBox;
if (p.Tag.ToString() == "PB0")
{
pb.SizeMode = PictureBoxSizeMode.StretchImage;
pb.Visible = true;
pb.BringToFront();
leave = true;
}
else
{
}
}
public void globalPbsMouseLeaveEvent(object sender, System.EventArgs e)
{
PictureBox p = sender as PictureBox;
if (p.Tag.ToString() == "PB0")
{
if (leave == true)
{
pb.Visible = false;
leave = false;
}
}
else
{
}
}
private void pb_MouseEnter(object sender, EventArgs e)
{
pb.SizeMode = PictureBoxSizeMode.StretchImage;
pb.Visible = true;
pb.BringToFront();
leave = true;
}
private void pb_MouseLeave(object sender, EventArgs e)
{
if (leave == true)
{
pb.Visible = false;
leave = false;
}
}
Just replace this pbs[0].Load(file_array[file_indxs]); with pbs[file_indxs].Load(file_array[file_indxs]);. Note that the file_indxs should be initialized to 0.
UPDATE
Try this to animate the PictureBox with the files list input:
//Use this custom PictureBox for convenience
public class AnimatedPictureBox : PictureBox {
List<string> imageFilenames;
Timer t = new Timer();
public AnimatedPictureBox(){
AnimateRate = 100; //It's up to you, the smaller, the faster.
t.Tick += Tick_Animate;
}
public int AnimateRate {
get { return t.Interval; }
set { t.Interval = value;}
}
public void Animate(List<string> imageFilenames){
this.imageFilenames = imageFilenames;
t.Start();
}
public void StopAnimate(){
t.Stop();
i = 0;
}
int i;
private void Tick_Animate(object sender, EventArgs e){
if(imageFilenames == null) return;
Load(imageFilenames[i]);
i = (i+1)%imageFilenames.Count;
}
}
//Now use the AnimatedPictureBox instead of the PictureBox
AnimatedPictureBox[] pbs = new AnimatedPictureBox[8];
//Animate all the PictureBoxes
for(int i = 0; i < file_array.Length; i++){
pbs[i].Animate(file_array[i]);
}
The getfiles should return the array of List<string>, assign the return value to the file_array you define in the outside scope:
//Note that you now don't need your timer1, just remove it.
private List<string>[] getfiles() {
//....
return file_array;
}
//When calling getfiles,
//you have to assign the file_array variable to the return value
List<string>[] file_array; //your variable, you defined it as string[],
//but it won't work, we have to use List<string>[]
file_array = getfiles();
NOTE: If you want to stop animation on a Picturebox, just call the method StopAnimate. That's all.
Hello I'm currently working on a windows from where I need to be able to add and remove a number of textboxes (and a lable) with a button click.
I have to have it set out within a tableLayoutPanel and Once "Add" is clicked a Label and 5 Text boxes must appear on the same row, and then when I click "Remove" they must dissapear, Hiding won't work as Data needs to be taken from them at a later stage but thats not an issue atm.
The problem is with the removal (I can add them fine as you'll see below) I know whats happening and can guess as to why but I need to find an alternate solution >.<
public partial class Form2 : Form
{
int Count = 1;
int rowIndex = 2, colIndex = 1;
Label Label;
TextBox Value;
TextBox Weight;
TextBox Width;
TextBox Height;
TextBox Length;
private void button1_Click(object sender, EventArgs e)
{
if (Count <= 9)
{
Count += 1;
rowIndex += 1;
tableLayoutPanel10.RowCount = +1;
AddLot(Count);
if (Count > 9)
button1.Enabled = false;
}
button2.Enabled = true;
}
private void button2_Click(object sender, EventArgs e)
{
if (Count == 2)
{
tableLayoutPanel10.Controls.Remove(Label);
tableLayoutPanel10.Controls.Remove(Value);
tableLayoutPanel10.Controls.Remove(Weight);
tableLayoutPanel10.Controls.Remove(Width);
tableLayoutPanel10.Controls.Remove(Height);
tableLayoutPanel10.Controls.Remove(Length);
Count -= 1;
rowIndex -= 1;
button2.Enabled = false;
}
else
{
tableLayoutPanel10.Controls.Remove(Label);
tableLayoutPanel10.Controls.Remove(Value);
tableLayoutPanel10.Controls.Remove(Weight);
tableLayoutPanel10.Controls.Remove(Width);
tableLayoutPanel10.Controls.Remove(Height);
tableLayoutPanel10.Controls.Remove(Length);
Count -= 1;
rowIndex -= 1;
button1.Enabled = true;
}
}
private void AddLot(int Count)
{
Label = new Label();
Label.Dock = DockStyle.Fill;
Label.Text = Count.ToString();
Label.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
Value = new TextBox();
Value.Dock = DockStyle.Fill;
Weight = new TextBox();
Weight.Dock = DockStyle.Fill;
Width = new TextBox();
Width.Dock = DockStyle.Fill;
Height = new TextBox();
Height.Dock = DockStyle.Fill;
Length = new TextBox();
Length.Dock = DockStyle.Fill;
tableLayoutPanel10.Controls.Add(Label, colIndex - 1, rowIndex);
tableLayoutPanel10.Controls.Add(Value, colIndex, rowIndex);
tableLayoutPanel10.Controls.Add(Weight, colIndex + 1, rowIndex);
tableLayoutPanel10.Controls.Add(Width, colIndex + 2, rowIndex);
tableLayoutPanel10.Controls.Add(Height, colIndex + 3, rowIndex);
tableLayoutPanel10.Controls.Add(Length, colIndex + 4, rowIndex);
}
}
All That Happens when I try to remove is the Last added Row of label/textboxes is removed, and then only the rowindex/count decrease on any clocks afterwards.
Any Ideas how to get this to work, I'll accept having to change it almost completely but as I said It must be done in the TableLayoutPanel >.<
Cheers,
Jmaru7
This works 100% for me i spent an hour working on it :
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
tableLayoutPanel1.RowCount = 1;
tableLayoutPanel1.ColumnCount = 6;
removeButton.Enabled = false;
}
private void addButton_Click(object sender, EventArgs e)
{
int index = tableLayoutPanel1.RowCount - 1;
Label label = new Label();
TextBox Value = new TextBox();
TextBox Weight = new TextBox();
TextBox Width = new TextBox();
TextBox Height = new TextBox();
TextBox Length = new TextBox();
label.Dock = DockStyle.Fill;
label.Text = (index + 1).ToString();
label.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
Value.Dock = DockStyle.Fill;
Weight.Dock = DockStyle.Fill;
Width.Dock = DockStyle.Fill;
Height.Dock = DockStyle.Fill;
Length.Dock = DockStyle.Fill;
int i = 0;
tableLayoutPanel1.Controls.Add(label, i++, index);
tableLayoutPanel1.Controls.Add(Value, i++, index);
tableLayoutPanel1.Controls.Add(Weight, i++, index);
tableLayoutPanel1.Controls.Add(Width, i++, index);
tableLayoutPanel1.Controls.Add(Height, i++, index);
tableLayoutPanel1.Controls.Add(Length, i++, index);
tableLayoutPanel1.RowCount += 1;
if (tableLayoutPanel1.RowCount > 9)
{
addButton.Enabled = false;
}
if (tableLayoutPanel1.RowCount > 0)
{
removeButton.Enabled = true;
}
}
private void removeButton_Click(object sender, EventArgs e)
{
if (tableLayoutPanel1.RowCount > 0)
{
int startIndex = ((tableLayoutPanel1.RowCount - 1) * 6) - 1;
for (int i = 0; i < 6; i++)
{
tableLayoutPanel1.Controls.RemoveAt(startIndex--);
}
tableLayoutPanel1.RowCount -= 1;
if (tableLayoutPanel1.RowCount == 0)
{
removeButton.Enabled = false;
}
if (tableLayoutPanel1.RowCount <= 9)
{
addButton.Enabled = true;
}
}
}
}
You are keeping only last added set of controls, you should keep all of them. Now when you delete last added controls, next delete uses reference to already deleted so it wont have any effect.
Best would be to make some storage class for set of the controls and keep them in some kind of collection.