Dynamically bind dropdown with month names - c#

I place a dropdownlist into my web page, then add following code to bind items to dropdown list within the page load event.
In this case is a dropdownlist with month names.
On this dropdownlist when the month changes, the previous months are no longer displayed and the previous month is no longer shown after the day 20th of the following month.
How can I also exclude from the list the months following the one on the list?
E.G.
At this time in the dropdownlist month list I have the months included from February to December
After the twentieth day of month February I will have in dropdownlist the months included from March to December
The question is to see only March in dropdownlist month and not see following months (from April to December...)
public partial class DD_Monthbind : Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Monthbind();
}
}
private void Monthbind()
{
DateTimeFormatInfo info = DateTimeFormatInfo.GetInstance(null);
int currentMonth = DateTime.Now.Month;
for (int i = 1; i < 13; i++)
{
bool isMonthInPast = ((i + 1) < currentMonth) || (i + 1 == currentMonth && DateTime.Now.Day > 20);
if (!isMonthInPast)
DropDownList1.Items.Add(new ListItem(info.GetMonthName(i), i.ToString()));
}
}
}
update
private void Monthbind()
{
DateTimeFormatInfo info = DateTimeFormatInfo.GetInstance(null);
int currentMonth = DateTime.Now.Month;
for (int i = 1; i < 13; i++)
{
bool isMonthInPast = (i < currentMonth) || (i == currentMonth && DateTime.Now.Day > 20);
if (!isMonthInPast)
{
DropDownList1.Items.Add(new ListItem(info.GetMonthName(i), i.ToString()));
}
}
foreach (ListItem item in DropDownList1.Items)
{
if (DropDownList1.Items.IndexOf(item) != 0)
{
item.Enabled = false;
}
}
}

Related

Get Numeric Value of Month With Combo Box C#

I have a combo box that I'm using to select a month out of a year. The months are provided through a List<> that I've set as the data source.
I believe I'm going about this the wrong way.
Code So Far:
private void btnExport_Click(object sender, EventArgs e)
{
int month = 0; //just a default value
if (cbMonth.SelectedText == "January")
month = 1;
else if (cbMonth.SelectedText == "Febuary")
month = 2;
else if (cbMonth.SelectedText == "March")
month = 3;
else if (cbMonth.SelectedText == "April")
month = 4;
else if (cbMonth.SelectedText == "May")
month = 5;
else if (cbMonth.SelectedText == "June")
month = 6;
else if (cbMonth.SelectedText == "July")
month = 7;
else if (cbMonth.SelectedText == "August")
month = 8;
else if (cbMonth.SelectedText == "September")
month = 9;
else if (cbMonth.SelectedText == "October")
month = 10;
else if (cbMonth.SelectedText == "November")
month = 11;
else if (cbMonth.SelectedText == "December")
month = 12;
int year = Int32.Parse(mtbYear.Text);
MessageBox.Show(month.ToString() + " " + year.ToString()); // to check values
}
My month never changes value and displays as 0. Which, I understand because I had given it the initial value of 0 in order to pass it to another method.
Question: How can I get the numeric value for the months when the user selects them from my combo box?
Show months in ComboBox:
comboBox1.DataSource = System.Globalization.CultureInfo.InvariantCulture
.DateTimeFormat.MonthNames.Take(12).ToList();
Select current month:
comboBox1.SelectedIndex = DateTime.Now.Month - 1;
Get selected month:
MessageBox.Show($"Month: {comboBox1.SelectedIndex + 1} - {comboBox1.SelectedItem}");
Have you tried the SelectedValue of the Combobox?
private void btnExport_Click(object sender, EventArgs e)
{
int month = 0; //just a default value
var monthNumber = DateTime.ParseExact((string)cbMonth.SelectedValue, "MMMM", CultureInfo.InvariantCulture).Month;
int year = Int32.Parse(mtbYear.Text);
MessageBox.Show(monthNumber.ToString() + " " + year.ToString()); // to check values
}
Don't forget to add try-catch for ParseExact
Hey whenever you see yourself using this many if elses, try to simplify the logic.
IDictionary<string, int> monthsDictionary = new Dictionary<string, int>()
{
{January,"1"},
{February, "2"},
{March,"3"}
/* And so on */
};
Declare this dictionary with the months you are using. Then you can just look at what the selected value of the cbo box is and use that as the key. Just make sure that the values in the cbo box match the keys in the dictionary. Like so.
private void btnExport_Click(object sender, EventArgs e)
{
month = monthsDictionary[cbMonth.SelectedText];
//This will give you the value of the key.
//Ex. If march is chosen then 3 is what is given back as an int.
int year = Int32.Parse(mtbYear.Text);
MessageBox.Show(month.ToString() + " " + year.ToString()); // to check values
}
I hope this helps!
You may use ParseExact method of DateTime. Ex -
var monthNumber = DateTime.ParseExact(cbMonth.SelectedText, "MMMM", CultureInfo.InvariantCulture).Month;
To get the numeric value from a list, i.e.
<asp:DropDownList ID="cbMonth" runat="server">
<asp:ListItem Selected="True" Value="1" Text="January"></asp:ListItem>
<asp:ListItem Value="2" Text="February"></asp:ListItem>
</asp:DropDownList>
The Selected value of this will give you the numeric value:
private void btnExport_Click(object sender, EventArgs e)
{
int month = cbMonth.SelectedValue;
}
Display the Month name at the font end but in value attribute store the month in number and when you select the month from combo box at that time in background you will get the month in digit

c# Web app How to get no of working days exclude weekends and public holidays

Background information
Just starting out to learn C#, im trying to build a simple web app that calculate the no of working day(s) between 2 dates.
The UI of the web app
The basic logic is when the user input a date (ie 01/05/2018) and click the button.It will calculate the total number of working day (exclude weekends and public holidays).
The problem now is the calculation isnt accurate ie between 23/05/2018 & 31/05/2018 it shows 6, it should be 7 days. And it doesnt take the dates into consideration during calculation
namespace testtest
{
public partial class First : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
//on btn click
protected void Button1_Click(object sender, EventArgs e)
{
string dt = TextBox1.Text;
DateTime dtDDMMYYYY = ParseDate(dt);
string dt2 = TextBox2.Text;
DateTime dtDDMMYYYY2 = ParseDate(dt2);
List<DateTime> list = new List<DateTime> {
DateTime.ParseExact("04/05/2018", "dd/MM/yyyy",
CultureInfo.InvariantCulture) };
DaysLeft(dtDDMMYYYY, dtDDMMYYYY2, true, list);
}
public DateTime ParseDate(string date)
{
DateTimeFormatInfo dateFormatProvider = new DateTimeFormatInfo();
dateFormatProvider.ShortDatePattern = "dd/MM/yyyy";
return DateTime.Parse(date, dateFormatProvider);
}
public int DaysLeft(DateTime startDate, DateTime endDate, Boolean
excludeWeekends, List<DateTime> excludeDates)
{
int count = 0;
for (DateTime index = startDate; index < endDate; index =
index.AddDays(1))
{
if (excludeWeekends && index.DayOfWeek != DayOfWeek.Sunday &&
index.DayOfWeek != DayOfWeek.Saturday)
{
bool excluded = false; ;
for (int i = 0; i < excludeDates.Count; i++)
{
if (index.Date.CompareTo(excludeDates[i].Date) == 0)
{
excluded = true;
break;
}
}
if (!excluded)
{
count++;
}
}
}
result.Text = count.ToString();
return count;
}
}
}
Keep it simple
public int DaysLeft(DateTime startDate, DateTime endDate, Boolean excludeWeekends, List<DateTime> excludeDates) {
int count = 0;
for (DateTime index = startDate; index <= endDate; index = index.AddDays(1)) {
if (excludeWeekends && (index.DayOfWeek == DayOfWeek.Sunday || index.DayOfWeek == DayOfWeek.Saturday))
continue;
if (excludeDates.Contains(index.Date))
continue;
count++;
}
return count;
}
If the date is a weekend and excludeWeekends flagged, continue on to next date, if date is included in excludeDates continue, else count the day.

how to create Schedule in c#

I'm new into programing and still learning. Currently I'm coding simple form for my schedule program (c#) in MS Visual Studio 2017. I already program day in month grid ( when you change date program generate gridview for it) but I have two important problem:
I would like to get day number in each cell, I tried use loop while and foreach but it doesn't work....
Second thing is that I would like to save my appointment in cell.
If its possible I would rather not use database, and I really don't want to use solutions that I would have to pay.
Here's my code:
namespace WindowsFormsApp1
{
public partial class Kalendarz : Form
{
public Kalendarz()
{
InitializeComponent();
}
private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
{
DateTime date_start = this.dateTimePicker1.Value;
this.textBox2.Text = date_start.ToString("hh-mm-dd-MM-yyyy"); // czas startu
this.textBox1.Text = date_start.ToString("MMMM");
int Month = date_start.Month;
int Year = date_start.Year;
int NoD = DateTime.DaysInMonth(Year, Month);
Decimal NoWD = Decimal.Divide(NoD, 7.0m);
if (NoWD > 4.1m)
{
int WN = 5;
dataGridView1.RowCount = WN;
int n0 = 1;
foreach(DataGridCell cell in dataGridView1)
{
while (n0 = NoD; n0++)
}
}
else
{
int WN = 4;
dataGridView1.RowCount = WN;
}
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if (checkBox1.Checked)
{
dataGridView1.Columns["s"].Visible = true;
dataGridView1.Columns["st"].Visible = true;
}
else if (!checkBox1.Checked)
{
dataGridView1.Columns["s"].Visible = false;
dataGridView1.Columns["st"].Visible = false;
}
}
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
}
}
Do you have any suggestions what can I do ?
I found something like that but I don't have any idea how to loop it
dataGridView.CurrentCell.Value = newValue.ToString ();
Be careful, what you whish for...
Regarding 1st request: This code will fill a DataGridView with day numbers, starting on the set day in week and not exceeding number of days in month, provided you have enough rows an columns, filling it from left to right (as opposed to i.e. top-down). I'd advice 7 columns, unless you want to have a lot of fun with calendar.
Guessing from your name, you're Polish and as far as I know week starts with Monday in Poland. You'd need a modification to the code for week starting with Sunday.
VB.NET:
Dim DayCounter As Int16 = 1
Dim DayInWeekStart As Int16 = 2 ' 1 = MON, 2 = TUE, 3 = WED, ...
Dim DayInMonthTotal As Int16 = 31
For ir = 0 To Me.dgv.rows.count - 1
For ic = 0 To Me.dgv.columns.count - 1 ' you should have 7 columns for MON-SUN in your DataGridView
If ir = 0 And (ic + 1) < DayInWeekStart And DayCounter < DayInMonthTotal Then
' skip / do nothing
Else
Me.dgv.rows(ir).cells(ic).value = DayCounter ' set DGV cell value to the date
DayCounter += 1 ' iterate day in month number
End If
Next
Next
C# (converted):
Int16 DayCounter = 1;
Int16 DayInWeekStart = 2;
// 1 = MON, 2 = TUE, 3 = WED, ...
Int16 DayInMonthTotal = 31;
For (ir = 0; ir <= this.dgv.rows.count - 1; ir++) {
// you should have 7 columns for MON-SUN in your DataGridView
For (ic = 0; ic <= this.dgv.columns.count - 1; ic++) {
If (ir == 0 & (ic + 1) < DayInWeekStart & DayCounter < DayInMonthTotal) Then {
// skip / do nothing
} else {
this.dgv.rows(ir).cells(ic).value = DayCounter;
// set DGV cell value to the date
DayCounter += 1;
// iterate day in month number
}
}
}
As for saving, the best option would be definitely a database, even though a structured text file is doable. If you have a lot of time...
For database, I'd use MERGE statement to UPDATE, DELETE or INSERT appointments.

Disable visibility of selection item in comboBox

I have a program consist of combo box:
Have the designer like:
this.month_list.AllowDrop = true;
this.month_list.FormattingEnabled = true;
this.month_list.Items.AddRange(new object[] {
"JAN",
"FEB",
"MAR",
"APR",
"MAY",
"JUN",
"JUL",
"AUG",
"SEP",
"OCT",
"NOV",
"DEC"});
this.month_list.Location = new System.Drawing.Point(35, 13);
this.month_list.Name = "month_list";
this.month_list.Size = new System.Drawing.Size(75, 24);
this.month_list.TabIndex = 13;
Now my question is it possible to disable the month selection visibility if month option is future or next to current month? Or in other words say now is march,so the user will not able to click APR,MAY and so-on. Any idea please advise.
Add a handler on the year ComboBox.SelectedIndexChanged, and in it repopulate the month list based on the current date and year selected.
If year is 2014, then don't add the month greater than the current one to your month list.
EDIT:
private void yearCombo_SelectedIndexChanged(object sender, EventArgs e)
{
if(int.Parse(yearCombo.Text) > DateTime.Now.Year)
{
//remove all entries from ComboBox
}
else if (int.Parse(yearCombo.Text) == DateTime.Now.Year)
{
//Just add the months up to current month
}
else
{
//Add all months
}
}
Sadly to tell that disable item in combobox only supported in VS2003-2005.
You may only remove them via the below code (If you wish to remove the item from the existing combobox):
// To remove item with index 0:
this.month_list.Items.RemoveAt(0);
// To remove currently selected item:
this.month_list.Items.Remove(this.month_list.SelectedItem);
// To remove "JAN" item:
this.month_list.Items.Remove("JAN");
The below code is combining the idea of Luc Morin's answer jonathanh8686's answer which you may find it helpful:
First you make a dictionary as what jonathanh8686's answer stated:
Dictionary<int,string> months = new Dictionary<int,string>();
months.add(1, "Jan");
months.add(2, "Feb");
Then everytime when the user change the year Combobox, you reset the month combobox as below:
private void yearCombo_SelectedIndexChanged(object sender, EventArgs e)
{
if(int.Parse(yearCombo.Text) > DateTime.Now.Year)
{
//remove all entries from ComboBox
this.month_list.Items.Clear();
}
else if (int.Parse(yearCombo.Text) == DateTime.Now.Year)
{
//Just add the months up to current month
this.month_list.Items.Clear();
int monthnumber = 1;
while(monthnumber <= DateTime.Now.Month)
{
this.month_list.Items.Add(months[monthnumber]);
monthnumber++;
}
}
else
{
//Add all months
this.month_list.Items.Clear();
int monthnumber = 1;
while(monthnumber <= 12)
{
this.month_list.Items.Add(months[monthnumber]);
monthnumber++;
}
}
}
I'm a newbie at C# so im not the best person to answer this but I have a idea about how to do this
I'm not sure about the exact code for this but heres a idea that could be used:
Make a datetime that contains the month
int month = 1;
int monthnumber = 1;
Datetime dt = new DateTime();
Then you could make a dictionary that has a key of the number month and key of the number of month so like:
Dictionary<int,string> months = new Dictionary<int,string>();
months.add(1, "Jan");
months.add(2, "Feb");
and so on...
after that do check for the month and look at the current month so if its March
if(dt.Month = March)
{
month = 3;
}
so then after that
add all the months that are less than 3 like this:
while(monthnumber < months)
{
this.month_list.Items.Add(dates.Value);
monthnumber++;
}
You would have to write custom code to draw the items of the combo box yourself.
Add these event handlers to the month list as well:
this.month_list.DrawMode = DrawMode.OwnerDrawFixed;
this.month_list.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.comboBox1_DrawItem);
this.month_list.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);
Font font = new Font("Aerial", 10, FontStyle.Regular);
bool DisableIndex(int index)
{
return index > DateTime.Now.Month - 1;
}
private void comboBox1_DrawItem(object sender, DrawItemEventArgs e)
{
Brush brushToDrawWith = DisableIndex(e.Index) ? Brushes.LightSlateGray : Brushes.Black;
e.Graphics.DrawString(this.month_list.Items[e.Index].ToString(), font, brushToDrawWith, e.Bounds);
}
void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (DisableIndex(month_list.SelectedIndex))
{
month_list.SelectedIndex = -1;
}
}

Convert.ToDateTime DD:HH:mm:ss C#/ASP.net GridView RowDataBound

The basis of my question is to color a cell in a ASP.net Grid View control.
I have a bound field that is produced from this in SQL
RIGHT('0' + CONVERT(varchar(6), SUM([Coaching]) / 86400), 2) + ':' + RIGHT('0' + CONVERT(varchar(6), SUM([Coaching]) % 86400 / 3600), 2) + ':' + RIGHT('0' + CONVERT(varchar(2), SUM([Coaching]) % 3600 / 60), 2) + ':' + RIGHT('0' + CONVERT(varchar(2), SUM([Coaching]) % 60), 2)
It is not great for working with I know but the Project rules that I have says I have to have in a format of DD:HH:MM:SS for the display.
All that being said I'm trying to do a row data bound event in C# to color the cell if it is over a certain Minute
protected void TheGrid_RowDataBound(object sender, GridViewRowEventArgs e)
{
//this is where we will color the columns
if (e.Row.RowType == DataControlRowType.DataRow)
{
int CoachingIndex = GetColumnIndexByName(e.Row, "Coaching");
DateTime CoachingValue = Convert.ToDateTime(e.Row.Cells[CoachingIndex].Text);
string columnValue = ((Label)e.Row.FindControl("Coaching")).Text;
if (Convert.ToDateTime(DataBinder.Eval(e.Row.DataItem, columnValue)) > Convert.ToDateTime("00:00:40:00"))
{
e.Row.Cells[CoachingIndex].BackColor = System.Drawing.Color.Red;
}
}
}
int GetColumnIndexByName(GridViewRow row, string columnName)
{
int columnIndex = 0;
foreach (DataControlFieldCell cell in row.Cells)
{
if (cell.ContainingField is BoundField)
if (((BoundField)cell.ContainingField).DataField.Equals(columnName))
break;
columnIndex++; // keep adding 1 while we don't have the correct name
}
return columnIndex;
}
This conversion if (Convert.ToDateTime(DataBinder.Eval(e.Row.DataItem, columnValue)) > Convert.ToDateTime("00:00:40:00")) is where the problem lies just trying to figure out how to get this to work in C# so I can do the comparison.
Any help will be appreciated.
Thank you for all the help I was able to work on it today after all the info provided was able to get it to work.
if (e.Row.RowType == DataControlRowType.DataRow)
{
int CoachingIndex = GetColumnIndexByName(e.Row, "Coaching");
TimeSpan timeStamp;
string timeStampString = e.Row.Cells[CoachingIndex].Text; // just change the index of cells to get the correct timestamp field
if (TimeSpan.TryParse(timeStampString, out timeStamp))
{
TimeSpan TS = timeStamp;
int mins = TS.Minutes;
int hours = TS.Hours;
int days = TS.Days;
if (mins > 40 || hours >= 1 || days >= 1)
{
e.Row.Cells[CoachingIndex].BackColor = System.Drawing.Color.Red;
}
}
}
}
int GetColumnIndexByName(GridViewRow row, string columnName)
{
int columnIndex = 0;
foreach (DataControlFieldCell cell in row.Cells)
{
if (cell.ContainingField is BoundField)
if (((BoundField)cell.ContainingField).DataField.Equals(columnName))
break;
columnIndex++; // keep adding 1 while we don't have the correct name
}
return columnIndex;
}
Try using a common safe function like that while parsing the date:
public DateTime? GetSafeDateTimeValue(object datetimeValue)
{
if (datetimeValue == null || datetimeValue == DBNull.Value)
return null;
else
{
try
{
if (!DateTime.TryParse(datetimeValue.ToString(), out tempDateTimeValue))
return null;
else
return tempDateTimeValue;
}
catch
{
return null;
}
}
}
And replace your line with
DateTime? dt = GetSafeDateTimeValue((DataBinder.Eval(e.Row.DataItem, columnValue)));
if(dt.HasValue)
if (dt.Value > Convert.ToDateTime("00:00:40:00"))
Second problem you will face that the date time parser must expect the year, instead of parsing the datetime string take datetime instance like below:
DateTime comparedDt = new DateTime(2014, 03, 10, 00, 40, 00);

Categories

Resources