I have a listview and I would like to cycle through it and determine if an action was completed by a certain time, in this case the action is reading a book. If the time in the column "ReadByThisTime" has passed for that particular book, I would like a message to display. How would I cycle through the listview in order to make sure each book has been read on time? Image of Listview
private void filllistview() //This is what is called to populate the listview
{
SqlConnection conn = new SqlConnection(@"conn");
using (SqlDataAdapter sda = new SqlDataAdapter(@"SELECT * FROM Books", conn))
{
//Fill the DataTable with records from Table.
System.Data.DataTable dt = new System.Data.DataTable();
sda.Fill(dt);
//Loop through the DataTable.
foreach (DataRow row in dt.Rows)
{
//Add Item to ListView.
ListViewItem item = new ListViewItem(row["Books"].ToString());
item.SubItems.Add(row["ReadByThisTime"].ToString());
item.SubItems.Add(row["ReadAt"].ToString());
listView1.Items.Add(item);
}
}
}
/* This is what I want my listview to perform
foreach(ListViewItem item in listView1.Items)
{
if(book is not read by time)
{
MessageBox.Show("Error")
}
}*/
CodePudding user response:
Here's what I would do. It's a little weird that the deadline only has time information without a date. So in the example below, I'm only comparing the time portion of the datetime variables.
private void alertForReadViolation() {
//This is what I want my listview to perform
foreach(ListViewItem item in listView1.Items)
{
//Datetime variables to hold datetimes parsed from listview strings.
//If you don't initialize with value, complier complains that the variables aren't assigned to
// in the main comparison.
DateTime deadline = DateTime.MaxValue;
DateTime readTime = DateTime.MinValue;
//Try to parse the deadline from the listview text.
if (!DateTime.TryParse(item.SubItems[1].Text, out deadline)) {
Console.WriteLine("Could not parse Read Deadline from list view string.");
return;
}
//Try to parse the readAt from the listview text.
if (!DateTime.TryParse(item.SubItems[2].Text)) {
Console.WriteLine("Could not parse ReadAt datetime from list view string.");
return;
}
//Compare only the time portion of the date variables since the deadline only contains time information.
if(TimeSpan.Compare(readTime.TimeOfDay, deadline.TimeOfDay) > 0)
{
MessageBox.Show("Error")
}
}
}
Alternatively, you could do the comparison when loading the listview. If you get the datetime data directly from the database DataRow, then it would be strongly typed and you wouldn't have to parse the dates/times from strings. Then, your main fill function would look like this:
private void filllistview() //This is what is called to populate the listview
{
SqlConnection conn = new SqlConnection(@"conn");
using (SqlDataAdapter sda = new SqlDataAdapter(@"SELECT * FROM Books", conn))
{
//Fill the DataTable with records from Table.
System.Data.DataTable dt = new System.Data.DataTable();
sda.Fill(dt);
//Loop through the DataTable.
foreach (DataRow row in dt.Rows)
{
//Add Item to ListView.
ListViewItem item = new ListViewItem(row["Books"].ToString());
//Get deadline data from database datetime field.
DateTime deadline = (DateTime)row["ReadByThisTime"];
item.SubItems.Add(deadline.ToString());
//Get ReadAt data from database datetime field.
DateTime readTime = (DateTime)row["ReadAt"];
item.SubItems.Add(readTime.ToString());
listView1.Items.Add(item);
//Compare only the time portion of the date variables since the deadline only contains time information.
if(TimeSpan.Compare(readTime.TimeOfDay, deadline.TimeOfDay) > 0)
{
MessageBox.Show("Error")
}
}
}
}