C# DateTime comparer skips from -1 to 1 - c#

Basically I am trying to write an alarm clock for a project (not graded). For some reason, my DateTime comparer skips from -1 to 1 immediately even though the values should be equal.
Is this because it's happening too fast or because I am not using milliseconds?
Here's the snippet of code where I think the problem is (alarmDate is null if it's not set yet):
private void Timer_Tick(object sender, EventArgs e)
{
lblTime.Content = DateTime.Now.ToLongTimeString();
if(alarmDate != null)
{
int result = DateTime.Compare(DateTime.Now, (DateTime)alarmDate.Value);
lblTest.Content = alarmDate.Value.ToLongTimeString();
lblTest2.Content = DateTime.Now.ToLongTimeString();
if(result == 0)
{
lblWakeUp.Content = "Wake Up!!!!";
SystemSounds.Beep.Play();
}
}
}
Sorry if this is a dumb question or mistake, but I really can't find the answer.
Thanks in advance!

DateTime has a precision in reality of about 16 milliseconds, so you have a very short window in which two DateTimes will be exactly equal, and it's very likely that the DateTime value you get will never equal a specific value. I would suggest using a flag that is triggered once the time goes past your alarm time:
bool alarmTriggered = false; // <-- new flag
private void Timer_Tick(object sender, EventArgs e)
{
lblTime.Content = DateTime.Now.ToLongTimeString();
if(alarmDate != null)
{
int result = DateTime.Compare(DateTime.Now, (DateTime)alarmDate.Value);
lblTest.Content = alarmDate.Value.ToLongTimeString();
lblTest2.Content = DateTime.Now.ToLongTimeString();
if(result > 0 && !alarmTriggered) // <-- check flag
{
alarmTriggered = true; // <-- set the flag
lblWakeUp.Content = "Wake Up!!!!";
SystemSounds.Beep.Play();
}
}
}

Related

FormatException when parsing decimals

I'm working on a code to do billing. This is a small portion of my code:
private void NightsLabel_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar) && e.KeyChar != '.')
{
e.Handled = true;
}
if (e.KeyChar == '.' && (sender as TextBox).Text.IndexOf('.') > -1)
{
e.Handled = true;
}
}
private void TotalButton_Click(object sender, EventArgs e)
{
RoomChargeLabel.Text = (Convert.ToInt64(NightRateLabel.Text) + Convert.ToInt64(NightsLabel.Text)).ToString();
}
I am struggling when I hit the Total Button Click void. Whenever I enter numbers that have decimals in them, it gives me an error:
System.FormatException: "Input string was not in a correct format".
Whenever I use whole numbers instead, it works just fine but I need to figure out why I can't do decimals.
Please help! :)
You are using Convert.ToInt64(NightRateLabel.Text), you should Use Convert.ToDouble(NightRateLabel.Text)
Or you can do a twin transform check
using System;
public class Program
{
public static void Main()
{
var doubleVal = "123123";
object fomattedValue = null;
try {
fomattedValue = Convert.ToInt64(doubleVal);
} catch {
fomattedValue = Convert.ToDouble(doubleVal);
}
Console.Write(fomattedValue.ToString());
}
}
As the others pointed out, the reason you are getting an error is because parsing a long (Int64) doesn't support decimal numbers:
// Only supports whole numbers, throws an exception for decimal places!
(Convert.ToInt64(NightRateLabel.Text) + Convert.ToInt64(NightsLabel.Text)).ToString();
I'm guessing NightRateLabel.Text is actually a currency (money) value. In that case, you should use decimal:
var nightRate = decimal.Parse(NightRateLabel.Text)
You can also handle failures more gracefully by using TryParse:
// You can inline this (remove var success = ...) of course, but I'm being verbose to demonstrate:
var success = decimal.TryParse(NightRateLabel.Text, out var nightRate);
if (!success)
{
// Handle parsing error gracefully: Show feedback to user, etc.
}
else
{
// Do something with nightRate
}

How can I automatically update column in datagridview base on the other column input

I have a datagridview dgvBlood and I have 4 columns Result, RangeFrom, RangeTo, Status. I just want to have a Status to be Normal or Abnormal based on the input in Result. If Result >= RangeFrom && Result <= RangeTo then Result = "Normal" else "Abnormal" RangeFrom and RangeTo is already given. User will just input Result and I just want to update it once the user has input.
Here's my sample code. And any help is appreciated.
private void dgvBlood_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
Double From = Convert.ToDouble(dgvBlood.CurrentRow.Cells["RangeFrom"].Value.ToString());
Double To = Convert.ToDouble(dgvBlood.CurrentRow.Cells["RangeTo"].Value.ToString());
Double Result = Convert.ToDouble(dgvBlood.CurrentRow.Cells["Result"].Value.ToString());
String value = "Normal";
String valueAb = "Abnormal";
if (Result >= From && Result <= To)
{
dgvBlood.CurrentRow.Cells["Status"].Value = value;
}
else
{
dgvBlood.CurrentRow.Cells["Status"].Value = valueAb;
}
}
Try following
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
Double From = Convert.ToDouble("0"+dataGridView1.CurrentRow.Cells["RangeFrom"].Value);
Double To = Convert.ToDouble("0" + dataGridView1.CurrentRow.Cells["RangeTo"].Value);
Double Result = Convert.ToDouble("0" + dataGridView1.CurrentRow.Cells["Result"].Value);
if (Result >= From && Result <= To)
{
dataGridView1.CurrentRow.Cells["Status"].Value = "Normal";
}
else
{
dataGridView1.CurrentRow.Cells["Status"].Value = "Abnormal";
}
}
You will have to put in a condition to check on which column change, status should change. Currently it will check for change in any cell.

How to Load all the Objects in an Array List

I am trying to figure out how to load through an Array List of Objects. I am able to retrieve the last Object in the Array, but it will not let me Load any other Object after that. here is part of the code I have. As you can see it saves the object to the List, but when I click the loadLastBtn it will only load the most recent entry and if I hit it again after that nothing loads.
List<Members> lstMembers = new List<Members>();
private int hold;
private void submitBtn_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(firstNameTxt.Text) || string.IsNullOrEmpty(lastNameTxt.Text)
|| string.IsNullOrEmpty(userNameTxt.Text) ||
string.IsNullOrEmpty(passwordTxt.Text) || string.IsNullOrEmpty(confPassTxt.Text)
|| string.IsNullOrEmpty(majorBox.Text) || string.IsNullOrEmpty(specialtyBox.Text))
{
MessageBox.Show("You must enter in all fields before moving forward");
}
else
{
Members m1 = new Members(firstNameTxt.Text, lastNameTxt.Text, userNameTxt.Text,
passwordTxt.Text, confPassTxt.Text, majorBox.Text,
specialtyBox.Text);
lstMembers.Add(m1);
}
}
private void loadLastBtn_Click(object sender, EventArgs e)
{
firstNameTxt.Text = lstMembers[hold].FirstName;
lastNameTxt.Text = lstMembers[hold].LastName;
userNameTxt.Text = lstMembers[hold].UserName;
passwordTxt.Text = lstMembers[hold].Password;
confPassTxt.Text = lstMembers[hold].ConfPassword;
majorBox.Text = lstMembers[hold].Major;
specialtyBox.Text = lstMembers[hold].Specialty;
hold++;
}
I have edited my answer. this will now print each user one by one each time I hit loadLastBtn, but it does show them from the first user to the last, where I need it to shower the last user to the first.
What you need is something like this:
// -1 Indicates that you should start at the end of the list
int index = -1;
private void loadButton_Click(object sender, EventArgs e)
{
if (members != null && members.Count > 0) // Avoid accessing if list is empty or null
{
if (index == -1)
index = members.Count - 1;
firstNameTxt.Text = lstMembers[index].FirstName;
lastNameTxt.Text = lstMembers[index].LastName;
userNameTxt.Text = lstMembers[index].UserName;
passwordTxt.Text = lstMembers[index].Password;
confPassTxt.Text = lstMembers[index].ConfPassword;
majorBox.Text = lstMembers[index].Major;
specialtyBox.Text = lstMembers[index].Specialty;
if (index == 0) // Reached beginning of array
index = -1; // Indicate that next time the last element must be accessed
else
--index;
}
}
private int hold = lstMembers.Count -1;
private void loadLastBtn_Click(object sender, EventArgs e)
{
firstNameTxt.Text = lstMembers[hold].FirstName;
lastNameTxt.Text = lstMembers[hold].LastName;
userNameTxt.Text = lstMembers[hold].UserName;
passwordTxt.Text = lstMembers[hold].Password;
confPassTxt.Text = lstMembers[hold].ConfPassword;
majorBox.Text = lstMembers[hold].Major;
specialtyBox.Text = lstMembers[hold].Specialty;
hold--;
}

Datagridview keeps locking/lagging when an update is performed to a row (to the cells at the row)

I'm updating my cells values from Yahoo's "Stock API". It works like a charm everything is updating properly , but when the updates are performed which is almost all the time since their in a timer with an interval at 3000 milliseconds. How can I get rid of this problem?
I tried suspending the layout and resuming, without success.
This is my own little teaching myself kinda project, so keep in mind that I never had anything with xml or datagridview to do before.
private void timer2_Tick(object sender, EventArgs e)
{
try
{
if (!(dataGridView.Rows[0].Cells[0].Value == null)) // Updates the rows idividualy as long as first row is not empty
{
for (int i = 0; i < dataGridView.RowCount; i++)
{
if (!(dataGridView.Rows[i].Cells[0].Value == null || dataGridView.Rows[i].Cells[0].Value.ToString() == "-")) // Makes sure that the row to update is not an empty row
{
String symbol;
symbol = Convert.ToString(dataGridView.Rows[i].Cells[0].Value);
String URLString2 = "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.quotes%20where%20symbol%20in%20(%22" + symbol + "%22)%0A%09%09&diagnostics=true&env=http%3A%2F%2Fdatatables.org%2Falltables.env";
dataGridView.ResumeLayout();
dataGridView.Update();
for (int t = 2; t < dataGridView.Columns.Count; t++)
{
dataGridView.SuspendLayout();
XmlTextReader reader2 = new XmlTextReader(URLString2); // Makes the reader read from the string abow ( URL )
string NasdaqOpenTime = "09:00:00";
// if the market haven't been open for the day then theres no DaysLow value
if (dataGridView.Columns[t].HeaderText == "DaysLow" && DateTime.Now.CompareTo(DateTime.Parse(NasdaqOpenTime)) == -1)
{
dataGridView.Rows[i].Cells[dataGridView.Columns[t].Index].Value = "-";
}
// if the market haven't been open for the day then theres no DaysHigh value
if (dataGridView.Columns[t].HeaderText == "DaysHigh" && DateTime.Now.CompareTo(DateTime.Parse(NasdaqOpenTime)) == -1)
{
dataGridView.Rows[i].Cells[dataGridView.Columns[t].Index].Value = "-";
}
else
{
reader2.ReadToFollowing(dataGridView.Columns[t].HeaderText); // Reada until it fins the elemnt Bid , then stops on it
reader2.ReadStartElement(dataGridView.Columns[t].HeaderText); // Recognizes Bid as start element (Bid)
dataGridView.Rows[i].Cells[dataGridView.Columns[t].Index].Value = reader2.ReadString(); // Reads the text in between (Declared as a string) actualy the bid value
reader2.ReadEndElement(); // Checks that the current nod is an end element (/Bid) if so then continue
reader2.ResetState();
}
}
}
}
}
}
catch (XmlException)
{
}
}
You better to request data update from Yahoo in a separate thread because it is taking long time. You can use System.Threading.Timer for that purpose.

Null Reference in editing a task scheduler trigger in c#

if (t != null) is always null why help..
when ever i try to get value in the variable name t it always gets in the else part but i am sure that there is valuse in tat variable.
private void button3_Click(object sender, EventArgs e)
{
try
{
if (search=="")
{
}
else
{
if (textBox1.Text=="")
{
MessageBox.Show("Select A Task Or Find One");
}
else
{
search = textBox1.Text;
}
}
if (search != null)
{
t = tasks.OpenTask(search);
if (textBox2.Text!="")
{
short hour = short.Parse(textBox2.Text.Substring(0, 2));
short minute = short.Parse(textBox2.Text.Substring(3, 2));
if (t != null) // this is null dont know why
{
foreach (Trigger tr in t.Triggers)
{
if (tr is StartableTrigger)
{
(tr as StartableTrigger).StartHour = hour;
(tr as StartableTrigger).StartMinute = minute;
}
}
t.Save();
t.Close();
}
tasks.Dispose();
button2.Visible = true;
textBox3.Visible = true;
search = "";
}
else
{
MessageBox.Show("Enter Time ");
}
}
}
catch (Exception b)
{
MessageBox.Show(b.ToString());
// MessageBox.Show("Select A Task From The List ");
}
}
help guys .. well i tried it to debug but didnt get a break through..
t is null because tasks.OpenTask(search) returns null.
Probably there is no task matching your search criteria.
Why are you disposing of tasks in the first place?
Any place in your source ,where you have written something like this MyClass t = new MyClass().. where t is your class object. If you have not declared,It will always come null.
Or might be you have declared something like this
private Task t; but forgot to add new keyword. Checkout!!!

Categories