I'm implementing backword function on a button. that when clicked moves to the previous link in the stack. the problem is this if it has one element in the stack pop() it gives an error of stack empty.
private void Backward_Click(object sender, EventArgs e)
{
try
{
if (simpleStack.Count != 0)
{
simpleStack.Pop();
string open = simpleStack.Pop();
PopulateListView(open);
complicatedStack.Push(open);
}
else if (simpleStack.Count == 0)
{
Backward.Enabled = false;
}
It works when I have more than one clicks n goes back to the previous item selected.but does not show the last one. I'm passing string in simpleStack. can anybody tell me what I'm missing?
Look at your code:
simpleStack.Pop();
string open = simpleStack.Pop();
You're popping twice, and ignoring the first result. Why would you do that? I suspect you can just remove the first Pop call.
Also note that your else clause doesn't need to check simpleStack.Count == 0 - it must be, otherwise you wouldn't be evaluating the else clause. (Unless you've got multiple threads doing stuff of course - which wouldn't be a good idea.)
Try this -
private void Backward_Click(object sender, EventArgs e)
{
try
{
if (simpleStack.Count != 0)
{
//simpleStack.Pop(); // Remove this line
string open = simpleStack.Pop();
PopulateListView(open);
complicatedStack.Push(open);
}
else if (simpleStack.Count == 0)
{
Backward.Enabled = false;
}
}
}
Related
I'm writing a FlashCard app in Windows Form.
Right now I'm trying to do is read word from string array and pass it to label. Then asking user to write the translation of this word. And finally pass the result to label box.
Here is my code:
public partial class EnglishPolishScreen : Form
{
//English words array
string[] words = new string[] { "word1", "word2", "word3", "word4" };
// meanings words array
string[] wordB = new string[] { "slowo1", "slowo2", "slowo3", "slowo4" };
int element = 0;
Thread thread;
public EnglishPolishScreen()
{
InitializeComponent();
}
private void CloseAppEvent(object sender, FormClosingEventArgs e)
{
Application.Exit();
}
private void button1_Click(object sender, EventArgs e)
{
thread = new Thread(Threadd);
thread.Start();
}
private void Threadd()
{
englishWord.Text = words[element];
counterLabel.Text = element + 1 + " of " + words.Length;
if (answerBox.Text.Equals(wordB[element]))
{
resultLabel.Text = "Good";
element++;
}
else
resultLabel.Text = "Bad";
if (element == words.Length)
{
element = 0;
}
}
private void EnglishPolishScreen_Load(object sender, EventArgs e)
{
englishWord.Text = words[element];
}
Edited
Guys, Why I have to click two times in button to see next item from array? And why I can see "bad" answer straight after I click button? The "Good" answer shows up after second click.
Edited v2.xD
Sorted. Anyway is it good way to write code like this? If not how It could look better? Thanks
Regards
On button click, it is going through the whole for loop, i.e. the entire list of meanings, you would have to break the for loop as soon as a right match is found. So just use break; after resoultLabel.Text = "Good answer!";. Also as pointed out by #Neil, it is not good to use UI in a separate background thread.
By the way, I am not able to wrap my head around the logic of chances. For giving chances you would have to declare a global variable which would get added/subtracted when the a bad answer is found after Iterating through whole for loop, disallowing any further trial for the word.
I have been trying to finish this small application for counting the number of attempts if you fail to write the correct pin code.
This is my code so far, and I am not understanding why my code isn't working and it keeps on incrementing non stop.
private void btn_login_Click(object sender, EventArgs e)
{
int attempts = 0;
int pin_number;
do
{
pin_number = int.Parse(txt_pin.Text);
MessageBox.Show("Hi There");
if (pin_number != 1326)
{
attempts++;
MessageBox.Show($"pin code is incorrect you have {attempts} of 3 attempts left");
txt_pin.Text = "";
txt_pin.Focus();
}
} while (pin_number == 1326 && attempts < 3);
}
Every time you click the button is an "attempt", correct? Well, what's the first thing you do every time you click the button...
int attempts = 0;
So every attempt is the first attempt. Except when the user gets it right. Then what you have is an infinite loop because the pin_number is correct and attempts is never incremented.
First, get rid of the loop entirely. There's no need to repeatedly check the same input. Once it's checked, it's checked. Second, track the number of attempts outside the scope of each attempt, such as at the class level. Third, check the number of attempts. Perhaps something like this:
private int attempts = 0;
private void btn_login_Click(object sender, EventArgs e)
{
int pin_number;
pin_number = int.Parse(txt_pin.Text);
MessageBox.Show("Hi There");
if (attempts < 3 && pin_number != 1326)
{
attempts++;
MessageBox.Show($"pin code is incorrect you have {attempts} of 3 attempts left");
txt_pin.Text = "";
txt_pin.Focus();
}
}
Now it's at least checking the pin as expected. Though at this point you have some logic to reconsider for your program. Off the top of my head...
It never notifies the user if they got the pin right. Perhaps something else should happen?
After the number of attempts is exhausted, there's no warning to indicate this. It looks exactly as it does if the pin is correct.
The text implies that the number of attempts is counting down, but it's actually counting up.
Perhaps something like this might get you started:
private int attempts = 3;
private void btn_login_Click(object sender, EventArgs e)
{
int pin_number;
pin_number = int.Parse(txt_pin.Text);
MessageBox.Show("Hi There");
if (attempts <= 0)
{
MessageBox.Show($"No more attempts left");
}
else if (pin_number != 1326)
{
attempts--;
MessageBox.Show($"Pin code is incorrect you have {attempts} attempts left");
txt_pin.Text = "";
txt_pin.Focus();
}
}
Examine each statement in the logic. For your own logic, particularly around if blocks and loops and whatnot, perhaps even grab a piece of paper and draw out the different code paths and write down in each path what should happen there. Every detail is important, such as when to show a message or when to modify a value. There's a lot of polish that can be added to this code, and I imagine it's an academic exercise so I'll leave that to you.
Right now you have a loop inside your button click handler. You probably don't want that since you want to enable the user to enter a new pin code and click the Login button again.
But that also means that you need to store the number of attempts outside the click handler, since it needs to be saved from one click to the next.
So if you change your code to something like this, I think you'll get the functionality you're after
private int attempts = 0;
private void btn_login_Click(object sender, EventArgs e)
{
int pin_number;
pin_number = int.Parse(txt_pin.Text);
MessageBox.Show("Hi There");
if (pin_number != 1326)
{
attempts++;
MessageBox.Show($"pin code is incorrect you have {3-attempts} of 3 attempts left");
txt_pin.Text = "";
txt_pin.Focus();
}
if (attempts >= 3)
{
btn_login.Enabled = false;
}
}
I'm having this wierd problem within the application I'm currently working on.
string searchText = "onMouseOver=\"CallList_onMouseOver(this);\" id=\"";
List<int> searchOrders = AllIndexesOf(scraper.clientBrowser.DocumentText, searchText);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < searchOrders.Count; i++)
{
string order = scraper.clientBrowser.DocumentText.Substring(searchOrders[i] + searchText.Length, 6);
scraper.clientBrowser.Document.GetElementById(order).InvokeMember("Click");
for (int j = 0; j < scraper.clientBrowser.Document.Window.Frames.Count; j++)
{
if (scraper.clientBrowser.Document.Window.Frames[j].Document != null && scraper.clientBrowser.Document.Window.Frames[j].Document.Body != null)
{
string orderText = scraper.clientBrowser.Document.Window.Frames[j].Document.Body.InnerText ?? "Nope";
//MessageBox.Show(j + Environment.NewLine + orderText);
if (!orderText.Contains("Nope"))
{
sb.AppendLine(orderText + Environment.NewLine);
}
}
}
}
Clipboard.SetText(sb.ToString());
The thing is, whenever I uncomment the MessageBox.Show, I can clearly see orderText is filled with another value than "Nope", the Stringbuilder gets filled, and the correct text is copied.
However if I comment the Messagebox.Show, the outcome of this loop is always "Nope". I'm stuck here, I have no idea what could cause something like this.
The scraper.clientBrowser is a System.Windows.Forms.WebBrowser.
Update:
Solved the issue by waiting for the document to be loaded, created this mechanism:
public bool DocumentLoaded
{
get { return documentLoaded; }
set { documentLoaded = value; }
}
private void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
this.DocumentLoaded = true;
this.clientBrowser = sender as WebBrowser;
}
void clientBrowser_Navigating(object sender, WebBrowserNavigatingEventArgs e)
{
this.DocumentLoaded = false;
}
Then in the class I'm using:
while(!scraper.DocumentLoaded)
{
System.Threading.Thread.Sleep(100);
}
It sounds like you need to ensure that the page is fully loaded, like there might be a race condition. I would suggest wiring up the WebBrowser.DocumentCompleted event, and then attempting your scrapping logic.
Update
I overlooked this initially, this certainly has something to do with your issue. The line where you are invoking a click, like so scraper.clientBrowser.Document.GetElementById(order).InvokeMember("Click");. This is done in the iteration, which will more than likely manipulate the DOM -- will it not? I suggest going about this problem entirely different. What are you trying to achieve exactly, (not how you're trying to do it)?
With this alone, I would suggest that you refer to this SO Q/A and look at how they're waiting for the click to finish.
Only one thing I can guest here:
When you uncomment MessageBox.Show, at the time the message box show the info, the clientBrowser use this time to finish loading page. Then when you press OK on message box, the page is load completed, so you get the result. When you comment it, you dont wai for page loaded, so the result is diffent.
Ok, so I have a program that checks a twitch url for whenever someone new follows the channel by comparing a certain string is different from a "temp" string that I use for reference. But instead of only outputting a message every time the string is different it gets stuck in a loop of outputting the latest follower and then second latest follower then latest follower again etc.
What am I missing? Also, is there a better way of checking if a certain string is updated?
private void DonationListen()
{
try
{
followers = this.donationClient.DownloadString("https://api.twitch.tv/kraken/channels/" + channel.Trim() + "/follows");
donationTimer.Interval = 10000;
donationTimer.Elapsed += new ElapsedEventHandler(CheckUpdates);
donationTimer.Start();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private void CheckUpdates(object source, ElapsedEventArgs e)
{
donationTimer.Stop();
int startIndex = followers.IndexOf("display_name\":") + 15;
int endIndex = followers.IndexOf(",\"logo", startIndex);
prevFollower = followers.Substring(startIndex, (endIndex - 1) - startIndex);
if (firstRun == true)
{
temp = prevFollower;
}
else if (prevFollower != temp)
{
//New follower detected
temp = prevFollower;
if (updateFollower != null)
{
updateFollower(prevFollower);
}
}
else
{
//Follower is the same as before
}
firstRun = false;
DonationListen();
}
I'm thinking it might have something to do with the downloadstring trying to get a new string from the url but failing since it's currently being updated and therefore the CheckUpdates doesn't have correct information or something?
Without a good code example, it is difficult to know for sure what the problem is. So we are left inspecting the code you did show us.
Based on that, it appears to me as though your "loop" is being caused by repeatedly subscribing to the same event.
In your DonationListen() method, you have this statement:
donationTimer.Elapsed += new ElapsedEventHandler(CheckUpdates);
In the CheckUpdates() method (i.e. the handler you are subscribing), you have this statement (as the very last statement):
DonationListen();
In other words, every time the timer's Elapsed event is raised, you add another event handler instance to the event. For every handler you add, the CheckUpdates() method will be called.
Again, without a good code example, it is difficult to know for sure what the best fix would be. But given the code that is here, it appears to me that you could just remove that last statement from the CheckUpdates() method, as the DonationListen() method does not appear to do anything that needs doing again.
I have a strange problem I'm checking in my code behind the user if he is active or not with as simple if .. in my Page_Load method as you can see here
private TimeReport paramTR;
private ZevUser zevUser;
protected void Page_Load(object sender, EventArgs e)
{
ZevUser user = ZevUser.GetById(Int32.Parse(Session["SessionId"].ToString()));
if (user == null)
{
this.Response.Redirect("~/About.aspx");
}
this.getParameters();
if (!this.IsPostBack)
{
if (paramTR.ZevUser.Active == 0)
{
this.Response.Redirect("~/TimeReporting/TimeReportPanel.aspx");
}
this.bindData();
}
}
But when I make a go throw to this method I get allays nullreferenceexception why so ever .. but the private ZevUser variable is not null it's full..
I really don't have a clue why is this happing, it would be really cool if someone could explain me this why this is happening
Thanks for help and fast answer
You need to break your code down so you can debug it easier or add logging if you cannot debug this code locally.
Remember that when debugging something, the worse mistake you can make is to make assumptions. Start from the beginning and follow the process through. Don't assume that the problem is something and don't assume that the problem can't be something:
I've included a broken down, more readable version below. You can now add logging around this or easily add breakpoints:
private TimeReport paramTR;
private ZevUser zevUser;
protected void Page_Load(object sender, EventArgs e)
{
this.getParameters();
if (!this.IsPostBack)
{
if ((this.paramTR != null) &&
(this.paramTR.ZevUser != null) &&
(this.paramTR.ZevUser.Active == 0))
{
this.Response.Redirect("~/TimeReporting/TimeReportPanel.aspx");
}
this.bindData();
}
string sessionId = Session["SessionId"] as string;
if (sessionId != null)
{
int session = int32.Parse(sessionId);
ZevUser user = ZevUser.GetById(session);
if (user == null)
{
this.Response.Redirect("~/About.aspx");
}
}
}
Why are you passing the session id to ZevUser.GetById()? I would expect this to take a user id, or for the method to be called something like ZevUser.GetBySessionId(). At the moment it's quite confusing.
This line is causing the issue:
ZevUser user = ZevUser.GetById(Int32.Parse(Session["SessionId"].ToString()));
This is because Session["SessionId"] can be null, and is null in this case.
If you are looking to get the SessionId that is set by ASP.net, then use this.Session.SessionID (source).
If you are storing a value in Session["SessionId"] that you are trying to retrieve, then do a null-check first:
if (Session["SessionId"] != null) { ...
You should consider testing the SessionId variable before using it by doing something like that :
if (!string.IsNullOrEmpty(Session["SessionId"].ToString()))
ZevUser user = ZevUser.GetById(Int32.Parse(Session["SessionId"].ToString()));
The best way to debug your exception is to enable debug when the exception is thrown.
For this, go to Debug>>Exceptions
and then enable first four checkboxes (maybe) and then try debugging the project. You will be halted at the position from where the exception will be thrown.