How to send variables from one button to another - c#

I have this so far on one of my programs and I would like it to be where if you press on one button to break up the number you enter, you enable another button to get that data and save it to an outfile.
private void button1_Click(object sender, EventArgs e)
{
string number = textBox1.Text;
int digits = int.Parse(number);
if (digits > 9999 || digits < 0)
{
MessageBox.Show("That is not a valid number");
}
else
{
int thousands = digits / 1000;
int hundreds = (digits - (thousands * 1000)) / 100;
int tens = (digits - ((hundreds * 100) + (thousands * 1000))) / 10;
int ones = (digits - ((tens * 10) + (hundreds * 100) + (thousands * 1000))) / 1;
label6.Text = thousands.ToString();
label7.Text = hundreds.ToString();
label8.Text = tens.ToString();
label9.Text = ones.ToString();
button2.Enabled = true;
}
I have this so far and it works but for button2, I want these variables that are generated from clicking button one to pass to button2 so when you click on it, it will use those variables to write to a file. Any ideas?

There are several ways, but looking at what you already have, why not just reread the labels back into the variables you want?
private void button2_Click(object sender, EventArgs e)
{
int thousands = Convert.ToInt32(label6.Text);
int hundreds = Convert.ToInt32(label7.Text);
//...etc
}
You could also just set globals instead of locals, ie declare your ints outside of any method call
int thousands;
int hundreds;
int tens;
int ones;
private void button1_Click(object sender, EventArgs e)
{
//...code
thousands = digits / 1000;
hundreds = (digits - (thousands * 1000)) / 100;
tens = (digits - ((hundreds * 100) + (thousands * 1000))) / 10;
ones = (digits - ((tens * 10) + (hundreds * 100) + (thousands * 1000))) / 1;
}
private void button2_Click(object sender, EventArgs e)
{
Console.WriteLine(thousands); //...etc
}
Don't do this too often as if you have tons of globals things can get confusing quick, but for a simple program (which this seems to be) it should be ok.

if it is a asp.net webforms application you can save the vars in the view state and retrieve them from the other button click
//setting
ViewState["thousands "] = thousands;
//Reading
int thousands = Convert.ToInt32(ViewState["thousands "]);
if it is console, windows app, windows service ou can just declare the int vars outside the event scope and you would be able to access them from both button click event;

Related

MouseClickEvent Counter multiplies on multiple clicks VS C#

When playing with clickevents in visual studio i came accross this error:
private void pictureBox1_Click(object sender, EventArgs e)
{
Testcounter = 0;
pictureBox1.MouseClick += myMouseClickEventFunction;
}
private void myMouseClickEventFunction(object sender, MouseEventArgs e)
{
int x = colors.GetUpperBound(0) + 1;
int y = colors.GetUpperBound(1) + 1;
Testcounter++;
var point = new Point(e.X - pictureBox1.Width/2, e.Y - pictureBox1.Height/2);
for (int i = 0; i < x; i++)
{
for (int u = 0; u < y; u++)
{
if (cirkles[i, u].Contains(point))
{
changeIndex(i, u);
}
}
}
this.Refresh();
}
The first time i click my picturebox the counters value is 1, the second time the value is 2, 3th time 3,... Does anyone has any idea why this happends? thnx
pic1
pic2
Because by executing this
pictureBox1.MouseClick += myMouseClickEventFunction;
You're adding the handler one more time with each click. Which should mean, that if you click it once, you add it once and it executes once. But with the second click, you add it one more time, so this time it will execute two times and that's why your counter is increasing to 2. What you need is to move your click handler somewhere else and register it only one time, which means that the best place to move it should be in the initialization of the form. (In public MainForm(){} or whatever form you're using the code in)
P.S.: Sorry for the poor english, I hope you understood me.

How to reset a picture boxes position back to the left side of the form?

I'm creating a basic racing game in C# for an assignment where two picture boxes race from the left side of the form to the right side. What I am struggling with is resetting the position back to the 1st pixel on the left side of the form once the picture box has reached the end of the form on the right side. At the moment the picture boxes just keep going right and then disappear from the form and never come back.
That is what the layout of the game looks like:
I've tried searching google for snippets of code or even examples on how I might achieve this and have yet to find anything.
Any help would be much appreciated.
public partial class frmRacing : Form
{
public frmRacing()
{
InitializeComponent();
}
//This is the segment of intergers and the randomizer.
Random r = new Random();
int dir = 1;
int min, sec, ms = 0;
private void btnExit_Click(object sender, EventArgs e)
{
this.Close();
}
//This is the timer for "Player One". It moves the players picture box across the form at a random speed between 1-10 and times how long it takes to complete the total laps.
private void tmrOne_Tick(object sender, EventArgs e)
{
dir = r.Next(1, 10);
picStark.Left += dir;
lblTimer1.Text = min + ":" + sec + ":" + ms.ToString();
ms++;
if (ms > 100)
{
sec++;
ms = 0;
}
else
{
ms++;
}
if (sec > 60)
{
min++;
sec = 0;
}
}
//This is the timer for "Player Two". It moves the players picture box across the form at a random speed between 1-10 and times how long it takes to complete the total laps.
private void tmrTwo_Tick(object sender, EventArgs e)
{
dir = r.Next(1, 10);
picLannister.Left += dir;
lblTimer2.Text = min + ":" + sec + ":" + ms.ToString();
ms++;
if (ms > 100)
{
sec++;
ms = 0;
}
else
{
ms++;
}
if (sec > 60)
{
min++;
sec = 0;
}
}
//This is the start button. It enables all the timers and starts the race.
private void btnStart_Click(object sender, EventArgs e)
{
tmrOne.Enabled = true;
tmrTwo.Enabled = true;
tmrThree.Enabled = true;
}
private void hsbLaps_Scroll(object sender, ScrollEventArgs e)
{
lblLaps3.Text = lblLaps3.Text + 1;
}
//This is the overall timer for the race.
private void tmrThree_Tick(object sender, EventArgs e)
{
lblTimer3.Text = min + ":" + sec + ":" + ms.ToString();
ms++;
if (ms > 100)
{
sec++;
ms = 0;
}
else
{
ms++;
}
if (sec > 60)
{
min++;
sec = 0;
}
}
}
You could create a method which you call at the end of your tick events which checks if the Left property is greater than the width of your form.
private void ResetPicture(PictureBox pb)
{
// check if picture box left property is greater than the width
// of your form - the width of your picturebox
if (pb.Left >= this.Width - pb.Width)
{
// the picture has won the game, reset it
pb.Left = 1;
}
}

C# Progress Bar based on number of lines in file

I would like to perform the following action in C#:
Read the amount of lines in a specific text file.
Depending on the amount of lines in a text file, read each line and update the progress bar.
This is what I have so far:
private void Form1_Load(object sender, System.EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
int lineCount = 0;
int max = 100;
float percent;
using (var reader = File.OpenText(#"C:\file.txt"))
{
toolStripLabel1.Text = "Initializing...";
while (reader.ReadLine() != null)
{
lineCount++;
}
reader.Close();
for (int i = 0; i < lineCount; i++)
{
percent = (max / lineCount);
toolStripLabel1.Text = i.ToString() + " - " + percent + "%";
bw.ReportProgress(Convert.ToInt32(percent));
percent = percent + percent;
// Thread.Sleep(100);
}
}
}
private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
// progressBar1.Value = (int)(((decimal)currentPosition / (decimal)length) * (decimal)100);
this.Text = e.ProgressPercentage.ToString();
}
Anyone have an idea on how to properly calculate and display the progress bar depending on what line is being read from the file?
Thanks in advance!
There are several problems with your code:
You're first reading the file, then after it has all been read you start updating the progress bar, which doesn't really make any sense.
You're doing integer division in your percentage calculation.
The percentage calculation isn't quite right.
You're updating the ToolStripLabel from the worker thread.
Try this:
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
var files = File.ReadAllLines( #"C:\file.txt" );
for( int i = 0; i < files.Length; i++ )
{
var line = files[i];
// do work on the current line here
int percentage = (int)( ( i / (double)files.Length ) * 100.0 );
bw.ReportProgress( percentage );
}
}
private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
toolStripLabel1.Text = e.ProgressPercentage.ToString() + "%";
this.Text = e.ProgressPercentage.ToString();
}
If the file is very large and it's the actual reading that takes time, you should go back to your original way of reading it, but update the progress for every line instead of after. Though then you're back to the issue of not knowing how many lines there are before you have read the file. In that case - you could estimate the progress based on how many bytes/chars you have read compared to the full size of the file, which you can get without reading it all.
There are a few things you need to do
try this : replace
percent = (max / lineCount);
with this
percent = (100.0 * i / lineCount);
and remove percent = percent + percent;
Try this:
private void InvokeLabel(string text)
{
if (toolStripLabel1.InvokeRequired)
{
toolStripLabel1.Invoke(new Action<string>(InvokeLabel), text);
}
else
{
toolStripLabel1.Text = text;
}
}
For your progress bar it's the same code

I have multiple text blocks that will be filled with numbers. I need them to totaled up together and then put into another text block

I am creating a golfing app. It is a 9 hole golf course. I created a page that has 9 separate text blocks that the user can enter in their score for each hole. Then I have a textbox that I want the final score to be put in. I know how to do this if I put a button to just add up all of the scores at the end, but what I am trying to get it to do, is to add them up once the score is put in. So when the user enters in their first score, the total box will put that one in it, then when the second score is put in its respective box, I want it to add that score to the total etc... for all 9 blocks.
I am creating this as a Windows Phone App with C#
private void Calculate_Click(object sender, RoutedEventArgs e)
{
int x1 = int.Parse(textBox1.Text);
int x2 = int.Parse(textBox2.Text);
int x3 = int.Parse(textBox3.Text);
int x4 = int.Parse(textBox4.Text);
int x5 = int.Parse(textBox5.Text);
int x6 = int.Parse(textBox6.Text);
int x7 = int.Parse(textBox7.Text);
int x8 = int.Parse(textBox8.Text);
int x9 = int.Parse(textBox9.Text);
int total = x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9;
TotalBlock.Text = total.ToString();
}
Try this one:
textBlock1.OnTextChanged += textChanged();
textBlock2.OnTextChanged += textChanged();
...
textBlock9.OnTextChanged += textChanged();
public void textChanged(object sender, EventArgs e){
int result = Convert.ToInt32(textBlock1.Text) + ... + Convert.ToInt32(textBlock9.Text);
finalTextBlock.Text = result.ToString();
}
If you put your TextBlock's in an array first, this becomes a lot simpler:
private TextBlock[] numberTextBlocks;
// Call this method at some point while setting up your UI
private void Initialize()
{
this.numberTextBlocks = new TextBlock[]
{
textBlock1, textBlock2, ...
};
foreach(t in this.numberTextBlocks)
{
t.OnTextChanged += NumberTextBlock_OnTextChanged;
}
}
private void NumberTextBlock_OnTextChanged(object sender, EventArgs e)
{
this.RecalculateTotal();
}
private void Calculate_Click(object sender, RoutedEventArgs e)
{
this.RecalculateTotal();
}
private void RecalculateTotal(object sender, RoutedEventArgs e)
{
int total = this.numberTextBlocks.Sum(t => int.Parse(t.Text));
TotalBlock.Text = total.ToString();
}

Multimedia timer interrupts in C# (first two interrupts are bad)

I am using Multimedia timer with a resolution of 1 ms and a period of 10 ms. The problem is that the multimedia timer badly interrupts for the first two events as I get a difference of 1 ms , which is not what I want.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.mmtimer.Tick += new System.EventHandler(this.mmtimer_Tick);
}
Multimedia.Timer mmtimer = new Multimedia.Timer();
private void Form1_Load(object sender, EventArgs e)
{
mmtimer.Resolution = 1;
mmtimer.Mode = Multimedia.TimerMode.Periodic;
mmtimer.Period = 10;
mmtimer.SynchronizingObject = this;
}
private void S_Click(object sender, EventArgs e)
{
TD.Items.Clear();
MT.Items.Clear();
delta_MT.Items.Clear();
double T = DateTime.Now.Hour * 60 * 60 * 1000 + DateTime.Now.Minute * 60 * 1000 + DateTime.Now.Second * 1000 + DateTime.Now.Millisecond;
Point C = Cursor.Position;
TD.Items.Add(C.ToString());
MT.Items.Add(T.ToString());
try
{
mmtimer.Start();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK,
MessageBoxIcon.Stop);
}
}
private void Stop_Click(object sender, EventArgs e)
{
mmtimer.Stop();
double T = DateTime.Now.Hour * 60 * 60 * 1000 + DateTime.Now.Minute * 60 * 1000 + DateTime.Now.Second * 1000 + DateTime.Now.Millisecond;
Point C = Cursor.Position;
TD.Items.Add(C.ToString());
MT.Items.Add(T.ToString());
M();
}
private void mmtimer_Tick(object sender, System.EventArgs e)
{
double T = DateTime.Now.Hour * 60 * 60 * 1000 + DateTime.Now.Minute * 60 * 1000 + DateTime.Now.Second * 1000 + DateTime.Now.Millisecond;
Point C = Cursor.Position;
TD.Items.Add(C.ToString());
MT.Items.Add(T.ToString());
}
void M()
{
for (int i = 0; i < MT.Items.Count - 1; i++)
{
double A1 = Convert.ToDouble(MT.Items[i + 1]);
double A2 = Convert.ToDouble(MT.Items[i]);
double d = A1 - A2;
delta_MT.Items.Add(d);
}
}
}
Could you please tell how to fix the first two interrupts? if it is possible.
When the multimedia timer is running at standard resolution before you change the resolution to 1, the timer will first complete its current period. The new period will only be effective after the next interrupt. Setting the multimedia timing is a synchronous job. Thus it may be delayed by as much as 20ms (interrupt period on some systems).
If you want to make sure that you timing scheme works from the start of your main code you should make the calls to the multimedia time configuration 2 interrupt periods ahead of the main code. I'd with 50 ms you should be OK.
The delay you observe for the first interrupts depends on when your call was made with respect to the systems interrupt.

Categories