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.
Related
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;
}
}
}
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
Good day, I'm having an error. I choose the August 5, 2015 on the date picker with the loop count of 3. But I'm having a problem. I'm using add 15 prior to the given output. But the first count is wrong.
THE OUTPUT IN THE FIRST COUNT IS
8/20/2015
but it should be
8/05/2015 because I use the 8/05/2015 on the datepicker.
I don't know what's the problem here.
Here's my code (This will be execute when the button "Calculate Schedule" is click"
private void execute_Click(object sender, EventArgs e)
{
var fromDate = date_from.Value; // Getting the value from DatePicker
int count;
for (count = 0; count < 3; count++) {
dgv_result.Rows.Add(1);
int numrows = count + 1;
fromDate = fromDate.AddDays(15);
dgv_result.Rows[count].Cells[1].Value = numrows; // Just for numbering the rows
dgv_result.Rows[count].Cells[0].Value = fromDate.ToShortDateString();
}
}
Here's my Screenshot
NOTE: Just check the Month only
You just have to put this line at the end of the loop:
for (count = 0; count < 3; count++)
{
dgv_result.Rows.Add(1);
int numrows = count + 1;
dgv_result.Rows[count].Cells[1].Value = numrows; // Just for numbering the rows
dgv_result.Rows[count].Cells[0].Value = fromDate.ToShortDateString();
//add days after adding the row, so next line will be effected by it
fromDate = fromDate.AddDays(15);
}
I am considering you're not using fromDate anywhere else and it is just for the loop.
You are adding days before you write your first row. So you need to .AddDays(15) at the end line of for loop.
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);
I'm trying to change the dates displayed in a RadCalendar. For example, I want it to begin 2 weeks before the current date and ends two weeks after the current date. Is it possible?
I was able to change the text displayed in the cells (to display the "new" date) but the "OnClick" methods still sends the "old" date.
OnDayRender I added :
e.Cell.Text = "" + _calStartDate.Day.ToString() + "";
_calStartDate = _calStartDate.AddDays(1);
But the calendar still thinks that the new dates are the old one, so the "SelectedDate" method returns the "old" date and the date selected is not the current date.
Is there a way to just pass a new list of dates, which would be easier?
UPDATE / Solution:
I was able to make it work like that:
private int rowCounter = 0;
private int rowHeaderCnt = 0;
private DateTime _startDate;
private DateTime _endDate;
private DateTime _calStartDate;
private DateTime _calEndDate;
protected void radCalendar_DayRender(object sender, Telerik.Web.UI.Calendar.DayRenderEventArgs e)
{
TableRow tr = (TableRow)e.Cell.Parent;
Table table = (Table)tr.Parent;
if (e.Day.Date.CompareTo(_calStartDate) < 0)
{
((TableRow)(e.Cell.Parent)).Style["display"] = "none";
}
else if (e.Day.Date.CompareTo(_calEndDate) > 0)
{
((TableRow)(e.Cell.Parent)).Style["display"] = "none";
}
else if (e.Day.Date.DayOfWeek == DayOfWeek.Sunday)
{
// This part will change the week number cell (if you don't display it, hide this part)
rowCounter++;
TableCell cellRowHeader = ((TableRow)(e.Cell.Parent)).Cells[0];
cellRowHeader.Text = rowCounter.ToString();
}
}
protected void Page_Load(object sender, EventArgs e)
{
radCalendar.RangeMinDate = _startDate;
radCalendar.RangeMaxDate = _endDate;
}
protected void radCalendar_HeaderCellRender(object sender, Telerik.Web.UI.Calendar.HeaderCellRenderEventArgs e)
{
if (e.HeaderType == Telerik.Web.UI.Calendar.HeaderType.Row)
{
rowHeaderCnt++;
e.Cell.Text = " " + rowHeaderCnt;
}
if (e.HeaderType == Telerik.Web.UI.Calendar.HeaderType.Column)
{
TableRow row = ((TableRow)(e.Cell.Parent));
row.Cells[0].Text = " " + StringUtil.getStringByLanguage("Week", "Sem.") + " ";
}
}
protected void raCalendar_SelectionChanged(object sender, Telerik.Web.UI.Calendar.SelectedDatesEventArgs e)
{
DateTime startDate = new DateTime();
DateTime endDate = new DateTime();
String url = String.Empty;
if (e.SelectedDates.Count == 1)
{
startDate = e.SelectedDates[0].Date;
endDate = e.SelectedDates[0].Date;
}
else
{
startDate = e.SelectedDates[0].Date;
endDate = e.SelectedDates[e.SelectedDates.Count - 1].Date;
}
// ... add code here with startDate and endDate
}
public void initCalendar(DateTime startDate, DateTime endDate)
{
this._startDate = startDate;
this._endDate = endDate;
this._calStartDate = startDate;
this._calEndDate = endDate;
while (this._calStartDate.DayOfWeek != DayOfWeek.Sunday)
{
this._calStartDate = this._calStartDate.AddDays(-1);
}
while (this._calEndDate.DayOfWeek != DayOfWeek.Saturday)
{
this._calEndDate = this._calEndDate.AddDays(1);
}
}
Based on my attempts, you can get very close to this setup. You have to use some trickery though, as the functionality, as far as I can tell, is not built into the calendar to only display the dates as you have asked for.
On page load:
protected void Page_Load(object sender, EventArgs e)
{
RadCalendar1.RangeMinDate = DateTime.Now.AddDays(-14);
RadCalendar1.RangeMaxDate = DateTime.Now.AddDays(14);
RadCalendar1.FirstDayOfWeek = (FirstDayOfWeek)DateTime.Now.AddDays(-14).DayOfWeek;
}
On day render:
protected void RadCalendar1_DayRender1(object sender, Telerik.Web.UI.Calendar.DayRenderEventArgs e)
{
if (e.Day.Date >= RadCalendar1.RangeMinDate.Date && e.Day.Date <= RadCalendar1.RangeMaxDate.Date)
{
e.Cell.Visible = true;
}
else
{
e.Cell.Visible = false;
}
}
This will get you an initial calendar load that shows 2 weeks back and 2 weeks forward and only allow the user to select inside that date. What it does not do, and I'd guess to be a separate question, is it does not execute the hiding of the dates outside the range when you page to the following month.
You must be aware that the format for the calendar must be 42 days, as per the design of the tool itself. That is why you see the blank line on top, as we are hiding those days. To my knowledge you can not remove them, only hide them or display them but not allow them to be clicked.