How to run a for loop after a for loop? - c#

I have a variable 'start' that initializes with a value 0.
How can i switch to a different loop when 1 argument becomes true.
So here is what i am trying to accomplish
when I click the button
1st Loop start with textBlock 1 containing "XXXX"
and Variable'Start' increment's by 1 everytime i click/touch till it reaches 34 . So when the counter reaches 34, the text changes to 'YYYY'
2nd Loop is when the counter resets and starts from 0 again but this time it only needs to go up till 33 . As soon as it reaches 33 the text changes to 'ZZZZ'.
Last Loop: The counter resets agains goes up till 33 . But this time when it finishes. It goes back to loop 1.
Here is the code that i have right now and I cannot seem to figure out how to do the last loop.
public partial class MainPage : PhoneApplicationPage
{
private int start = 0;
private bool sw = false;
// Constructor
public MainPage()
{
InitializeComponent();
int start = 0;
}
private void button1_Click(object sender, RoutedEventArgs e)
{
tasbih();
}
public void tasbih()
{
if (sw == false)
{
textBlock1.Text = "TEXTBX 1";
}
start++;
String text1 = Convert.ToString(start);
textBlock2.Text = text1;
if (start >= 35)
{
textBlock1.Text = "TEXTBX 2";
start = 0;
String text2 = Convert.ToString(start);
textBlock2.Text = text2;
sw = true;
}
}
private void button2_Click(object sender, RoutedEventArgs e)
{
textBlock1.Text = "Reset";
tasbih();
}
Also i have a reset button that starts everything all over no matter where you are in the counter. Any pointers as to how i can do that ?

I suggest you have a more explicit state variable, and key off of that for all your logic. You're currently keying off of start only for the transition to sw = true, it'll be easier if you have an explicit state.
enum MyState { Part1, Part2, Part3 }
MyState currentState = Part1;
int clickCount = 0;
public void tasbih()
{
clickCount++;
// First, do state transitions.
switch(currentState)
{
case MyState.Part1:
if(clickCount >= 34) { currentState = MyState.Part2; clickCount = 0; }
break;
case MyState.Part2:
if(clickCount >= 33) { currentState = MyState.Part3; clickCount = 0; }
break;
case MyState.Part3:
if(clickCount >= 33) { currentState = MyState.Part1; clickCount = 0; }
break;
}
// Now, act on the current (or new) state.
switch(currentState)
{
case MyState.Part1:
textBlock1.Text = "TEXTBX 1";
textBlock2.Text = clickCount.ToString();
break;
case MyState.Part2:
textBlock1.Text = "TEXTBX 2";
textBlock2.Text = clickCount.ToString();
break;
case MyState.Part3:
textBlock1.Text = "ZZZZ";
textBlock2.Text = clickCount.ToString();
break;
}
}
private void button2_Click(object sender, RoutedEventArgs e)
{
currentState = MyState.Part1;
clickCount = 0;
tasbih();
}

// these have to be member variables, or you'll never be able to reset
// or even remember the counter between calls
private int clicks = 0; // the number of clicks in the current loop
private int state = 0; // which loop we're in
// these are just so we don't have to repeat ourselves.
// each element corresponds to a possible value of `state`.
// both arrays should have the same number of elements.
// alternatively, you could have a type containing the label and max together,
// and just have an array of those.
private string[] labels = { "TEXTBX 1", "TEXTBX 2", "ZZZZ" };
private int[] max = { 34, 33, 33 };
public void reset() {
clicks = 0;
state = 0;
// probably reset text boxes here too. If you don't want to, then delete
updateTextBoxes();
}
public void bump()
{
// bump the counter, and if it's high enough, switch to the next state
// and reset the counter
// (the "% max.Length" causes 3 to be 0, so states wrap around)
if (++clicks > max[state])
{
state = (state + 1) % max.Length;
clicks = 0;
}
updateTextBoxes();
}
private void updateTextBoxes() {
textBlock1.Text = labels[state];
textBlock2.Text = clicks.ToString();
}

Related

C # infinite loop help basic programming

I'm in my second quarter of c # programming and i'm working on a POS application. I have my windows form created and I have my basic code done for the first week it was assigned. Now I have to "idiot-proof" my code by making sure that only correct data can be entered. Here's what I have so far:
private void btnAddItem_Click(object sender, EventArgs e)
{
//Declare variables
double dblSalesTax = 0, dblPrice, dblTax, dblSalesPrice;
string strItem, strTaxAdded;
int intQuantity;
bool diffTest = false;
//Process user input
while (!diffTest)
{
diffTest = double.TryParse(txtSalesTax.Text, out dblSalesTax);
}
while (dblSalesTax < 0 || dblSalesTax > 25)
{
MessageBox.Show("Please enter a valid tax.");
txtSalesTax.Clear();
diffTest = false;
}
intQuantity = Convert.ToInt16(txtQuantity.Text);
dblPrice = Convert.ToDouble(txtPrice.Text);
dblSalesPrice = dblPrice * intQuantity;
strItem = cbxItem.Text;
intQuantity = Convert.ToInt16(txtQuantity.Text);
dblSubtotal += dblSalesPrice;
if (chkTaxExempt.Checked)
{
dblTax = 0;
strTaxAdded = "";
}
else
{
dblTax = dblSalesPrice * dblSalesTax;
strTaxAdded = "*";
}
dblTaxTotal += dblTax;
lbxTally.Items.Add(strItem + ", " + dblSalesPrice.ToString("C") + strTaxAdded);
//Reset Form
txtPrice.Clear();
txtQuantity.Clear();
chkTaxExempt.Checked = false;
cbxItem.Focus();
}
private void btnEndSale_Click(object sender, EventArgs e)
{
dblGrandTotal = dblSubtotal + dblTaxTotal;
lbxTally.Items.Add("");
lbxTally.Items.Add("");
lbxTally.Items.Add("Subtotal: " + dblSubtotal.ToString("C"));
lbxTally.Items.Add("Tax Total: " + dblTaxTotal.ToString("C"));
lbxTally.Items.Add("Grand Total: " + dblGrandTotal.ToString("C"));
}
private void btnPay_Click(object sender, EventArgs e)
{
double dblPay, dblChange;
dblPay = Convert.ToDouble(txtPay.Text);
dblChange = dblPay - dblGrandTotal;
lbxTally.Items.Add("");
lbxTally.Items.Add("Amount Paid: " + dblPay.ToString("C"));
lbxTally.Items.Add("Change: " + dblChange.ToString("C"));
}
Variables being declared beforehand and diffTest being initialized as false.
The assignment is to make sure that the sales tax entered is between 0 and 25 and that they can't enter words or anything else. I thought I did it right but when I run it, I have an infinite loop on my message box and I can't figure out how to get out of it correctly (entering break just gets me out but keeps the input). I have google'd to my hearts content but haven't found a solution but I feel like it's because my code is reusing what's in the text box automatically (I could be very wrong!). Once I get this i'll have to "idiot-proof" my other inputs but I haven't tried yet cause I'm still stuck on this first one. I'm a beginner programming student so any help is appreciated.
You don't need a while statement there. Change it to:
if (dblSalesTax < 0 || dblSalesTax > 25)
Because you have there a while loop as soon as you step into that loop you will never get out because your condition will be always true.
My guess is that you should change While to If.
private void btnAddItem_Click(object sender, EventArgs e)
{
//Declare variables
double dblSalesTax = 0, dblPrice, dblTax, dblSalesPrice;
string strItem, strTaxAdded;
int intQuantity;
bool diffTest = false;
//Process user input
//While (!diffTest)
//{
diffTest = double.TryParse(txtSalesTax.Text, out dblSalesTax);
//}
// Check if the value gets parsed and is in range, otherwise show error and
//exit from this handler
If (!diffTest || dblSalesTax < 0 || dblSalesTax > 25) '<--- Change While to If
{
MessageBox.Show("Please enter a valid tax.");
txtSalesTax.Clear();
diffTest = false;
return; // Return from here since validation failed
}
...
...
...
}
May you can try using Parallel.Invoke(() => DoSomeWork(), () => DoSomeOtherWork()); withawait for the the task that has your loop, something like below:
Parallel.Invoke(
() =>
{
Console.WriteLine("Begin first task...");
}, // close first Action
async () =>
{
Console.WriteLine("Begin second task...");
while (true)
{
// HERE you are the code you need to be executed in infinite loop
await Task.Delay(60000);
}
}, //close second Action
() =>
{
Console.WriteLine("Begin third task...");
} //close third Action
); //close parallel.invoke
Console.WriteLine("Returned from Parallel.Invoke");

How can i get from a window only the text without the Handle number?

I have two classes that get all the minimized windows:
The first class is WindowSnap.cs:
WindowSnap.cs
The second class is WindowSnapCollection.cs:
WindowSnapCollection.cs
In the first class in the windowSnap there is a method called GetAllWindows:
public static WindowSnapCollection GetAllWindows(bool minimized, bool specialCapturring)
{
windowSnaps = new WindowSnapCollection();
countMinimizedWindows = minimized;//set minimized flag capture
useSpecialCapturing = specialCapturring;//set specialcapturing flag
EnumWindowsCallbackHandler callback = new EnumWindowsCallbackHandler(EnumWindowsCallback);
EnumWindows(callback, IntPtr.Zero);
return new WindowSnapCollection(windowSnaps.ToArray(), true);
}
In the end i used a breakpoint on the return line and windowSnaps variable contain 15 items.
For example the first item is:
[0] = {Window Text: , Handle: 31918532}
The second one is:
[3] = {Window Text: ?How can i get from a window only the text without the Handle number ? - Stack Overflow - Google Chrome?, Handle: 64424060}
In the first item i was able to do on my own to remove this item since it's text is only "," and this window show nothing.
But number [3] and other items i want first to remove from them the part Handle: 64424060
I don't need that the user will see this information. But only the text so for example number [3] should look like:
?How can i get from a window only the text without the Handle number ? - Stack Overflow - Google Chrome?
And to fix those "?" that are in the beginning of the line.
But the idea is to display only the name of each window and not the whole text with the handle number.
This is how i add the items(windows) to form1 listBox:
this.listBoxSnap.Items.AddRange(WindowSnap.GetAllWindows(true, true).ToArray());
In the listBox i want to see the items names or description/titles not the whole text with the handle number.
You can do a little trick. It is not nice but works. Add a new listbox eg listBox1 with the same size on top of listBoxSnap.
add in public Form1():
public Form1()
{
...
for (int i = listBoxSnap.Items.Count - 1; i >= 0; i--)
{
string tt = listBoxSnap.Items[i].ToString();
if (tt.Contains(" ,"))
{
listBoxSnap.Items.RemoveAt(i);
}
}
buttonSnap.Enabled = true;
//add here ->
string[] myList = new string[listBoxSnap.Items.Count];
for (int i = 0; i < listBoxSnap.Items.Count; i++)
{
string tt = listBoxSnap.Items[i].ToString();
int index = tt.LastIndexOf(",");
myList [i] = tt.Substring(0, index);
}
listBox1.Items.AddRange(myList);
rectangles = new Rectangle[listBoxSnap.Items.Count];
isCropped = new bool[listBoxSnap.Items.Count];
if (this.listBoxSnap.Items.Count > 0)
{
this.listBoxSnap.SetSelected(0, true);
this.listBox1.SetSelected(0, true);
}
listBoxSnap.Select();
listBox1.Select();
}
change private void listBoxSnap_SelectedIndexChanged(object sender, EventArgs e) to:
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
listBoxSnap.SelectedIndex = listBox1.SelectedIndex;
drawpicbox(this.listBoxSnap.SelectedIndex);
}
and delete this.listBoxSnap.SelectedIndexChanged += new System.EventHandler(this.listBoxSnap_SelectedIndexChanged); from Form1.Designer.cs
Add this event:
private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
var item = listBox1.IndexFromPoint(e.Location);
if (item >= 0)
{
listBox1.SelectedIndex = item;
listBoxSnap.SelectedIndex = listBox1.SelectedIndex;
cm.Show(listBox1, e.Location);
}
}
}
And lastly add in private void RefreshWindowsList()
private void RefreshWindowsList()
{
...
for (int i = listBoxSnap.Items.Count - 1; i >= 0; i--)
{
string tt = listBoxSnap.Items[i].ToString();
if (tt.Contains(" ,"))
{
listBoxSnap.Items.RemoveAt(i);
}
}
//add here ->
string[] myList = new string[listBoxSnap.Items.Count];
for (int i = 0; i < listBoxSnap.Items.Count; i++)
{
string tt = listBoxSnap.Items[i].ToString();
int index = tt.LastIndexOf(",");
myList [i] = tt.Substring(0, index);
}
listBox1.Items.Clear();
listBox1.Items.AddRange(myList);
rectangles = new Rectangle[listBoxSnap.Items.Count];
isCropped = new bool[listBoxSnap.Items.Count];
textBoxIndex.Text = listBoxSnap.Items.Count.ToString();
if (this.listBoxSnap.Items.Count > 0)
{
this.listBoxSnap.SetSelected(0, true);
this.listBox1.SetSelected(0, true);
}
listBoxSnap.Select();
listBox1.Select();
}
Valter

Global array not being accessed correctly

Below is my current code:
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public int[] trialArray = new int[10];
public int trialCounter = -1;
private void button1_Click(object sender, EventArgs e)
{
bool button1Click = true;
if (button1Click == true)
{
ITIpanel.Visible = true;
for (int i = 0; i < trialArray.Length; i++) { trialArray[i] = -1; } // Set default value through array
int counter = 0;
Random rnd = new Random();
while (counter < 10 / 2)
{ // Red trials, fill half array
int index = rnd.Next(0, 10 - 1);
if (trialArray[index] == -1) { trialArray[index] = 1; ++counter; } //if unchanged value, change it
}
while (counter < 10)
{
int index = rnd.Next(0, 10);
if (trialArray[index] == -1) { trialArray[index] = 2; ++counter; }
}
}
}
private void ITIpanel_Paint(object sender, PaintEventArgs e)
{
if (ITIpanel.Visible == true)
{
trialCounter += 1;
timer1.Enabled = true;
}
}
private void timer1_Tick(object sender, EventArgs e)
{
ITIpanel.Visible = false;
timer1.Enabled = false;
if (trialArray[trialCounter] == 1) { redstimPanel.Visible = true; }
else { bluestimPanel.Visible = true;}
if (trialCounter == 9) { Application.Exit(); }
}
public int counter = 0;
public event EventHandler Clicked5TimesEvent;
private void OnClicked5TimesEvent()
{ if (Clicked5TimesEvent != null) { Clicked5TimesEvent(this, EventArgs.Empty); } }
private void bluestimPanel_MouseDown(object sender, EventArgs e)
{
//FR requirement
counter++; if (counter % 5 == 0) { redstimPanel.Visible = false; ITIpanel.Visible = true; }
}
private void redstimPanel_MouseDown(object sender, EventArgs e)
{
//FR requirement
counter++; if (counter % 5 == 0) { redstimPanel.Visible = false; ITIpanel.Visible = true; }
}
}
}
As you can see, I am attempting to make a global array with 10 items. On the button click the 10 items are supposed to be altered such that half contain the value 1 and the other half contain the value 2.
Then, on the timer tick, depending on the value in the trialCounter, which determines the part of the array to be accessed, it should display either the redstimPanel or the bluestimPanel.
Therefore, if the 'trialCounter' is equal to 8, and 8 in the TrialArray is equal 1, the 'redstimPanel' should become Visible. Alternatively, if 8 in the 'TrialArray' is equal to 2, the 'bluestimPanel' should become Visible.
This, however, is not working as I would like it to. Thus, there are clearly some issues with my code. Do you all have any suggestions?
You never reset counter, or have the second loop (the one setting the 2s) be the full array.
There is also an error with the random number, rnd.Next(a,b) a - lower bound (inclusive), b - upper bound (exclusive). So it should be rnd.Next(0,10); so you have a chance of populating the last array position.
while (counter < 10 / 2) { // Red trials, fill half array
int index = rnd.Next(0, 10);
if (trialArray[index] == -1) { trialArray[index] = 1; ++counter; } //if unchanged value, change it
}
//Counter on the first loop here is already 5 (it exited the previous loop)
//So allow it to get to 10, and populate the FULL array.
while (counter < 10) {
int index = rnd.Next(0, 10);
if (trialArray[index] == -1) { trialArray[index] = 2; ++counter; }
}
Allow me to give you some tips and some explanations regarding your code:
First of all, you probably wanted that local button1Click variable to know later on whether the button has been clicked or not. For that to work, you should place it outside that function, otherwise it's never going to be used, and will be true with every button click, something like this:
bool button1Click = false;
private void button1_Click(object sender, EventArgs e)
{
if (!button1Click)
{
When you have a condition, you want the code to decide, whether an expression is true or false you may omit the part "== true" because it doesn't add anything new.
You have two whiles. Your idea was to run the counter until 5, with the first piece of code, and then from 5 to 10 the second piece of code. Now let me try to explain what is actually going on. The counter will go on until 5 filling 1s at random indices. Then at 5, the expression in the while will become false and it breaks out from the loop. Since the second while has the very same expression, it simply avoids it and goes on. One of the many solutions would be to have an if in the loop like this:
while (counter < 10)
{
if (counter<5)
{
// fill red
}
else
{
// fill blue
}
}
The way you fill up the values in your array. Have you thought about what's going to happen when the same index will be generated several times? It means it'll overwrite the previous value while certain index will remain -1.

Timer and List<string> in C#

I need help with timer and List.
List consist of collection of string say 5 or 6 at a time. Now, I want to display string one on label1 and it should wait for 5s and then display string 2 on label1. I have timer control and I am specifying my code in timer_tick event.
private void timer1_Tick(object sender, EventArgs e)
{
string[] myStatus = myStatusCollection.ToArray();
int length = myStatus.Length;
for (int i = 0; i < length; i++)
{
string _myStatus = myStatus[i];
//label1.ResetText();
MessageBox.Show("Twitter Status =" + _myStatus);
//label1.Text = _myStatus;
//label1.Visible = true;
}
}
I have specify, Elapse = true and interval = 5000 but still I am not able to display one string at a time. In fact, I am getting last string only. I want to rotate the strings all time.
Can anyone help me.
That's because you're looping through all the strings each time the timer event fires.
Store your index in a private variable and use that instead.
private int _index = 0;
private void timer1_Tick(object sender, EventArgs e)
{
string[] myStatus = myStatusCollection.ToArray();
string _myStatus = myStatus[_index];
//label1.ResetText();
MessageBox.Show("Twitter Status =" + _myStatus);
//label1.Text = _myStatus;
//label1.Visible = true;
if(_index == (myStatus.Length - 1))
_index = 0;
else
_index++;
}
Well it is doing just what you told it to. However, what you told it to do is not what you meant for it to do. Try this.
public class Form1 : Form {
private string[] statuses = { "A", "B", "C", "D", "E" }; // Init with proper values somewhere
private int index = 0;
private void OnTimerTick(object sender, EventArgs e) {
string status = statuses[index];
index++;
if (index == statuses.Length) { // If index = Array.Length means we're
// outside bounds of array
index = 0;
}
}
}
I'd create an int outside of the Tick to hold your position. Make sure you reset it back to 0 when you restart the process.
int MyPosition = 0;
private void timer1_Tick(object sender, EventArgs e)
{
string[] myStatus = myStatusCollection.ToArray();
int length = myStatus.Length;
if((MyPosition + 1) > length)
{
//Index Out of Range
}
else
{
string _myStatus = myStatus[MyPosition];
label1.Text = _myStatus
}
MyPosition++;
}

C# reassigning array values(down one step ex 5-4) that are within an object during a event

Just learning C# (along with object and event programing) and the teacher didn't really show us how to get things done.
class Postion
{
private int[] x_coordinate = new int[100];
private int[] y_coordinate = new int[100];
private double[] speed = new double[100];
private int[] direction = new int[100];
const int MAX_SPEED = 50;
int counter = 0;
public Postion()
{
x_coordinate[counter] = 0;
y_coordinate[counter] = 0;
speed[counter] = 0;
direction[counter] = 0;
}
//get set methods
public int X
{
get
{
return x_coordinate[counter];
}
set
{
x_coordinate[counter] = value;
}
}
There is one more Class between them
The values are frist assigned by a button click.
Airplane newplane = new Airplane();
private void BtnCreate_Click(object sender, EventArgs e)
{
bool box = txtName.Text != "";
if (box == true)
newplane.Name = txtName.Text;
else { }
box = txtx.Text != "";
if (box == true)
newplane.PlanePostion.X = int.Parse(txtx.Text);
else { }
Etc.
I can call on the array values for display for the list box.
private void lsbplanes_SelectedIndexChanged(object sender, EventArgs e)
{
placeholder = newplane.PlanePostion.Counter;
newplane.PlanePostion.Counter = lsbplanes.SelectedIndex;
if (newplane.PlanePostion.Counter < 0)
newplane.PlanePostion.Counter = 0;
else { }
lblxshow.Text = Convert.ToString(newplane.Getx());
but when using a destroy button to remove an item in the list box I need to have it so the box updates with the new values when the user selects the item in the listbox.
This is what I have to try and do it so far, it sets all the ones above to 0s but does remove the the deleted one fine
private void BtnKill_Click(object sender, EventArgs e)
{
if (lsbplanes.SelectedIndex == -1)
{
MessageBox.Show("Please select an item first.", "No item selected", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
else
{
placeholder = lsbplanes.SelectedIndex;
newplane.PlanePostion.Counter = lsbplanes.Items.Count;
while (newplane.PlanePostion.Counter > placeholder)
{
placex = newplane.PlanePostion.X;
placey = newplane.PlanePostion.Y;
placespeed = newplane.Getspeed();
placedic = newplane.Getdirection();
newplane.PlanePostion.Counter--;
newplane.PlanePostion.X = placex;
newplane.PlanePostion.Y = placey;
newplane.PlanePostion.Speed = placespeed;
newplane.PlanePostion.Direction = placedic;
}
lsbplanes.Items.RemoveAt(lsbplanes.SelectedIndex);
newplane.PlanePostion.Counter = lsbplanes.Items.Count;
}
anyone can help me on this?
I was torn in this question, answer exactly what your problem is, or suggest that you redesign it.
#Marc is right you should be using some sort of List<Position> on your Plane object (or a ReadOnlyObservableCollection<Position>).
#Marc is also right, that the problem you are having is that you are trying to push the values down from the end of the list and overwriting them. In these cases it is better to start from the deletion point and pull them down.
So if you have {1,2,3,4,5,6,7,8,9,10} and you delete from item 5, you would have {1,2,3,4,10,10,10,10,10,10}. The code below will let you end up with {1,2,3,4,6,7,8,9,0}
placeholder = lsbplanes.SelectedIndex;
int idx = placeholder;
while (idx < lsbplanes.Items.Count)
{
newplane.PlanePosition.Counter = idx+1;
placex = newplane.PlanePostion.X;
placey = newplane.PlanePostion.Y;
placespeed = newplane.Getspeed();
placedic = newplane.Getdirection();
newplane.PlanePostion.Counter = idx;
newplane.PlanePostion.X = placex;
newplane.PlanePostion.Y = placey;
newplane.PlanePostion.Speed = placespeed;
newplane.PlanePostion.Direction = placedic;
idx++;
}
// Need to zero out elements at the end
newplant.PlanePosition.Counter = lsbplanes.Items.Count;
/* Zeroing code goes here */
newplane.PlanePosition.Counter = placeholder;
lsbplanes.Items.RemoveAt(lsbplanes.SelectedIndex);

Categories

Resources