my user control doesn't show up on the forms design - c#

I'm trying to create a calendar for my project and I created a blank user control to use it for each day for a week.
the user control i created is like this:
However, when I run the .cs file , there aren't any changes on the form. The expected output should be something like this:
My form output, but there aren't any "temporary" user controls:
What may be the reason of this problem?
This is my code:
private void displayDays()
{
DateTime now = DateTime.Now;
// getting the first day of the month
DateTime startofthemonth = new DateTime(now.Year, now.Month, 1);
// getting the count of days of the month
int day = DateTime.DaysInMonth(now.Year, now.Month);
// conver the startofthemont to integer
int dayoftheweek = Convert.ToInt32(startofthemonth.DayOfWeek.ToString("d"));
// i created here a blank user control from project >> add user control
for(int i = 1; i < dayoftheweek; i++)
{
UserControlBlank ucblank = new UserControlBlank();
// daycontainer is flowLayoutPanel
daycontainer.Controls.Add(ucblank);
}
}

startofthemonth.DayOfWeek is already an int, so there is no need to convert it to a string and then back again.
The problem is the first day of January 2023 is a Sunday, and the value for Sunday is zero (0), so your loop never runs because 1 is not less than 0!
If the intent was to create an entry for each day of the month, then you need to modify your for loop:
// getting the count of days of the month
int daysInMonth = DateTime.DaysInMonth(now.Year, now.Month);
for(int i = 1; i <= daysInMonth; i++)
{
UserControlBlank ucblank = new UserControlBlank();
// daycontainer is flowLayoutPanel
daycontainer.Controls.Add(ucblank);
}
If the intent was to create just the starting week, starting with the first day of the month and ending with the last day of the first week (Saturday), then:
for(int i = startofthemonth.DayOfWeek; i <= DayOfWeek.Saturday; i++)
{
UserControlBlank ucblank = new UserControlBlank();
// daycontainer is flowLayoutPanel
daycontainer.Controls.Add(ucblank);
}

Related

C# How to get the "greyed" days of a month DateTime

In Windows 10 calendar, as an example, we find an grid of 7x6 days that represents each day of the month, but is obvious that no month has 42 days, so "overflowed" days, by any means, the days that show in the grid but isn't of current month is greyed out as a day of another month. Is there some easy way to get these days on C# with DateTime class?
For example, in 2020/08, the "greyed days" is: 26, 27, 28, 29, 30, 31 (days of the previous month) and 1, 2, 3, 4, 5 (days of the next month).
In case that isn't clear, this is a screenshot showing the days that i'm referring
I couldn't find any question that relates my question.
Edit:
The best answer is by #ChilliPenguin, this is my implementation:
public static MonthGrayDays GrayDays(this DateTime time) {
List<DateTime> before = new List<DateTime>();
List<DateTime> after = new List<DateTime>();
DateTime firstDay = new DateTime(time.Year, time.Month, 1);
DateTime prevMonth = firstDay.AddDays(-1);
DateTime nextMonth = firstDay.AddMonths(1);
int daysInMonth = DateTime.DaysInMonth(time.Year, time.Month);
for (int a = 0; a < (int)firstDay.DayOfWeek; a++)
{
before.Add(prevMonth.AddDays(-a));
}
before.Reverse();
int count = before.Count();
for (int b = 0; b < 42 - count - daysInMonth; b++)
{
after.Add(nextMonth.AddDays(b));
}
return new MonthGrayDays {previousMonth = before, nextMonth = after};
}
This is an Extension method of DateTime class, it returns a custom class that returns the dates before and after the month, the class is implemented as follow:
public class MonthGrayDays {
public List<DateTime> previousMonth;
public List<DateTime> nextMonth;
}
To use the extension method, just call:
DateTime now = new DateTime(2020, 8, 1);
foreach (DateTime date in now.GrayDays().previousMonth) {
Console.WriteLine(date.Day);
}
Console.WriteLine("/");
foreach (DateTime date in now.GrayDays().nextMonth) {
Console.WriteLine(date.Day);
}
I don't think there's an automatic solution, but the logic is simple enough to step through. The most important thing is the DateTime.DayOfWeek property. It returns a DayOfWeek enum value corresponding to Sunday through Saturday which can be cast to an int ranging from 0 to 6 accordingly.
Take your month and construct a DateTime object corresponding to the 1st of the month. Now take its DayOfWeek and cast to int, and now you have the number of grey days at the top of the calendar. Getting the number from the end of the month is equally simple. Build a DateTime object for the last day of the month and cast its DayOfWeek to an int and subtract from 6 to get the number of grey days.
If you need to dates for those grey days, start at first day of the month and subtract 24 hours to get the last day of the previous month. The grey days for the end of the calendar can be assumed to start at 1.
Using the DateTime and DateTimeOffset Structs you could calculate for the first day of the month's type of day using the Day of week function. This would return an enum. If you convert the enum to an int(note, 0 = sunday, which does correlate with the windows calender) you would be able to loop back to get those dates. I would recommend using a List to store these dates, but I do not know your current situation :)
for (int a = 0; a < (int)FirstDay.DayOfWeek; a++)
{
graydays.Add(prevmonth.AddDays(-a));
}
To get the dates after the current month we could get the count of the days listed, the number of days in the month, and the grid area(42 in this case) to calculate the amount of days after the month that we need to consider.
int count = graydays.Count();
for (int b = 0; b < 42 - count - daysinmonth; b++)
{
graydays.Add(LastDayOfMonth.AddDays(b));
}
Note, To get the daysinmonth, you need to use the DateTime.DaysInMonth() function, and to get the Last day, just add 1 month to the first day, and then subtract a day.

Check if selected date is within three days of a predefined holiday

This is for a program at work. I don't have access to the code right now, but I really want to figure this out, so I wrote a quick program at home that is a mimic of my work project.
I need to know if that date is within 3 working days of a "holiday". If it is, then the selected date must be incremented by one to skip over the holiday. Example:
If there is a holiday on "01/19/2018" and a user selects "01/16/2018", then the program must skip the 19th and then set the closing date as "01/20/2018". Now if I do pure if/then statements, I can get it to work as expected, but the problem then becomes: "what if both 01/19/2018 AND 01/20/2018 are holidays?" This is where I'm stuck.
At work, I'm using a SQL table that already has a column for dates in "MM/dd/yyyy" format (so those dates are my list source that I am checking against.) The user opens a calendar and selects a date. I'm actually parsing an XML file that is created by another method that actually touches the database then using XElement for an iteration that puts all those dates in a string list.)
This is the code in my pseudo work program:
private void button1_Click(object sender, EventArgs e)
{
DateTime dt = DateTime.Now;
txtLog.Text = dt.ToString("MM/dd/yy") + Environment.NewLine;
List<string> allexemptdays = new List<string>();
string[] days = { "11/19/2018", "11/20/2018" };
foreach (string a in days)
{
allexemptdays.Add(a);
}
foreach (string a in allexemptdays)
{
ToLog(a);
}
DateTime eq = DateTime.Parse(txtDate.Text);
string thefrustrationisreal = eq.ToString("MM/dd/yy");
if (Math.Abs(DateTime.Now.Subtract(eq).Days) <= 3)
{
MessageBox.Show("Date exemption found.");
}
}
private void ToLog(string a)
{
txtLog.Text += ("Array value to list: " + a + Environment.NewLine);
}
private void monthCalendar1_DateSelected(object sender, DateRangeEventArgs e)
{
txtDate.Text = monthCalendar1.SelectionStart.ToString("MM/dd/yy");
}
Obviously I understand "DateTime.Now" doesn't reflect what I require, but I was just playing more with the DateTime class.
So in short: I'm creating an array with the dates (similar to my real program)
Iterating through them, adding them to a list. Now I need to check if the selected date falls within 3 days of the predefined date from a returned value from my sql table.
If a date is found, move the closing date up a day; however, if holidays in a row are found, then skip those two dates altogether. I can do this on a one by one basis (using if/then) but this doesn't work well if two holidays are back to back of each other.
As a side note, I want to be able to tell if the selected date is within 3 days AND moves over to another month, but I think I can handle that with DateTime, checking the days in a month and incrementing when needed (or I'm sure DateTime could do that for me actually.) I'm not too worried about this concern though at this point.
I did accept Mike's answer as it does work as intended, but! I now have a different issue
Now the "days.count()" holds a persistent number after the user selects a date beyond the holidays. Example: Selecting January 21 2017 returns "Janurary 26 2017" as the closing date because it's still counting the 20th and 21st as holidays affected by the range, when it should just set the closing date now at "Janurary 24th 2017"
I've played around with the code provided; I can't find a good way to fix it. I was thinking something along the lines of:
If(selectedDate.AddDays(3) >= holidaydate) then do a check for another day through the datetime list, but I'd still be making that way more complicated than it should be (I think.)
Last entry I'll do to this post (I'm considering this post solved now):
Matt's answer I selected does work to an extent and I appreciate his help. Problem is, the .Count() never resets, so if you go past the holiday(s) dates, it always holds onto the skipped days (so instead of going to 3 days ahead of the selected date, it'll go (3+the total number of days counted))
In the event someone else comes across a situation like this, here's what I ended up doing:
Downloaded the "WorkingDaysManagement" reference, instructions from:
https://github.com/Opturne/WorkingDaysManagement
the code I ultimately used is:
private void button1_Click(object sender, EventArgs e)
{
txtLog.Text = null;
DateTime dt = DateTime.Now;
var sd = (DateTime.Parse(txtDate.Text));
Console.WriteLine(sd.ToShortDateString());
var listHolidays = new List<DateTime>
{
new DateTime(2017, 12, 24),
new DateTime(2017, 12, 25)
};
var listWeekEnd = new List<DayOfWeek>
{
DayOfWeek.Saturday,
DayOfWeek.Sunday
};
var helper = new WorkingDayHelper(listHolidays,listWeekEnd);
foreach(DateTime s in helper.GetSpanDates(sd,3))
{
Console.WriteLine("Current iteration date: "+s.ToShortDateString());
}
var nextworkday = (helper.GetSpanDates(sd, 3).Last().ToString());
txtLog.Text += ("Next working day available: " + nextworkday + Environment.NewLine);
if(helper.IsWorkingDay(sd)==true)
{
txtLog.Text += ("It is a working a day." + Environment.NewLine);
}
else
{
txtLog.Text += ("NOT a working day!" + Environment.NewLine);
}
txtEndDate.Text = nextworkday;
}
The author of the plugin was gracious enough to put his work under the MIT license as well.
Let's say you have parsed all the date strings from the database into a List<DateTime> namely holidays. Then you can do something like
// Parsed holidays in a list, we will use LINQ against it.
var holidays = new List<DateTime> {
new DateTime(2017, 1, 19),
new DateTime(2017, 1, 20),
};
// Selected Date. In your case it would be: DateTime.Parse(txtDate.Text);
var selectedDate = new DateTime(2017, 1, 16);
// Count how many holidays there are within 3 days from the selcted date.
var count = holidays.Count(holiday => holiday - selectedDate <= TimeSpan.FromDays(3));
// Then add the count and 3 to the selected date
var closingDate = selectedDate.AddDays(count + 3);
// Now we have to make sure the closing date is not a holiday.
if (count > 0)
{
int skipDays = 0;
while (holidays.Any(holiday => holiday == closingDate.AddDays(skipDays)))
{
// holidays list contains the date. Skip it.
skipDays++;
}
closingDate = closingDate.AddDays(skipDays);
}

How do I calculate the no of days, from input type checkboxes (I have weekdays as checkboxes)

I have two input fields - date 1 and date2 I calculated the difference between two dates using jquery. let say it is 29 Now I have to check if a checkbox of Monday is checked true then out of 29 days, there will be 4 mondays then that would be my answer i.e. my result would be 4. Similarly, If have monday tuesday wednesday selected then I have to calculate that out of 29 there will be how many occurences of m,t,w and hence how much would be my result
// assume here days are 23, 29 or whatever
var days = PageUtils.GetDaysBetweenDates(start, end);
//adding code for days calculation
var selected = [];
$('#weekDaysOptions input:checked').each(function () {
selected.push($(this).attr('name'));
});
// get the count of weekdays selected.
var daysoFWeekare = selected.length;
// value of selected will be = 1, if out of 7 weekdays one is checked true, if 2 are checked then selected will be 2 and so on.
You cant just use the difference in days because you have to know what day you started on. If you use the difference to loop and add days to start then record each day youll get a 7 index array with the number of occurences of each day.
Something like this should work:
start = new Date(2017,9,14)
end = new Date(2017,9,24)
var days = (end - start)/(1000*60*60*24)// 10 days just for example, you already have this number
var daysOfWeek = [0,0,0,0,0,0,0]// array to hold results
for(var i = 0; i < days;i++){
x = start.getDay();
daysOfWeek[x] += 1;
start = addDays(start,1);
}
console.log(daysOfWeek)
function addDays(date, days) {
var result = new Date(date);
result.setDate(result.getDate() + days);
return result;
}

Get DateTime of the next nth day of the month

If given a date and a variable n, how can I calculate the DateTime for which the day of the month will be the nth Date?
For example, Today is the 17th of June.
I would like a function that when provided 15 would return the DateTime for July 15.
A few more examples:
Today is Feb. 26: Function would return March 30 when provided 30.
Today is Dec. 28. Function would return Jan 4 when provided 4.
Today is Feb. 28. Function would return March 29 when provided 29, unless it was a leap year, in which case it would return Feb 29.
Why not just do?
private DateTime GetNextDate(DateTime dt, int DesiredDay)
{
if (DesiredDay >= 1 && DesiredDay <= 31)
{
do
{
dt = dt.AddDays(1);
} while (dt.Day != DesiredDay);
return dt.Date;
}
else
{
throw new ArgumentOutOfRangeException();
}
}
After many, many edits, corrections and re-writes, here is my final answer:
The method that follows returns a a DateTime representing the next time the day of number day comes up in the calendar. It does so using an iterative approach, and is written in the form of an extension method for DateTime objects, and thus isn't bound to today's date but will work with any date.
The code executes the following steps to get the desired result:
Ensure that the day number provided is valid (greater than zero and smaller than 32).
Enter into a while loop that keeps going forever (until we break).
Check if cDate's month works (the day must not have passed, and the month must have enough days in it).
If so, return.
If not, increase the month by one, set the day to one, set includeToday to true so that the first day of the new month is included, and execute the loop again.
The code:
static DateTime GetNextDate3(this DateTime cDate, int day, bool includeToday = false)
{
// Make sure provided day is valid
if (day > 0 && day <= 31)
{
while (true)
{
// See if day has passed in current month or is not contained in it at all
if ((includeToday && day > cDate.Day || (includeToday && day >= cDate.Day)) && day <= DateTime.DaysInMonth(cDate.Year, cDate.Month))
{
// If so, break and return
break;
}
// Advance month by one and set day to one
// FIXED BUG HERE (note the order of the two calls)
cDate = cDate.AddDays(1 - cDate.Day).AddMonths(1);
// Set includeToday to true so that the first of every month is taken into account
includeToday = true;
}
// Return if the cDate's month contains day and it hasn't passed
return new DateTime(cDate.Year, cDate.Month, day);
}
// Day provided wasn't a valid one
throw new ArgumentOutOfRangeException("day", "Day isn't valid");
}
The spec is a little bit unclear about to do when today is the dayOfMonth. I assumed it was it to return the same. Otherwise it would just be to change to <= today.Day
public DateTime FindNextDate(int dayOfMonth, DateTime today)
{
var nextMonth = new DateTime(today.Year, today.Month, 1).AddMonths(1);
if(dayOfMonth < today.Day){
nextMonth = nextMonth.AddMonths(1);
}
while(nextMonth.AddDays(-1).Day < dayOfMonth){
nextMonth = nextMonth.AddMonths(1);
}
var month = nextMonth.AddMonths(-1);
return new DateTime(month.Year, month.Month, dayOfMonth);
}
Stumbled upon this thread today while trying to figure out this same problem.
From my testing, the following seems to work well and the loop only needs two goes (I think? Maybe 3 max(?)) to get to the answer:
public static DateTime GetNearestSpecificDay(DateTime start, int dayNum)
{
if (dayNum >= 1 && dayNum <= 31)
{
DateTime result = start;
while (result.Day != dayNum)
result = dayNum > result.Day ? result.AddDays(dayNum - result.Day) : new DateTime(result.Month == 12 ? result.Year + 1 : result.Year, (result.Month % 12) + 1, 1);
return result;
}
else
return DateTime.Today;
}
Edit: As requested, here's a less compact version that walks through the logic step by step. I've also updated the original code to account for a required year change when we reach December.
public static DateTime GetNearestSpecificDay(DateTime start, int dayNum)
{
// Check if target day is valid in the Gregorian calendar
if (dayNum >= 1 && dayNum <= 31)
{
// Declare a variable which will hold our result & temporary results
DateTime result = start;
// While the current result's day is not the desired day
while (result.Day != dayNum)
{
// If the desired day is greater than the current day
if (dayNum > result.Day)
{
// Add the difference to try and skip to the target day (if we can, if the current month does not have enough days, we will be pushed into the next month and repeat)
result = result.AddDays(dayNum - result.Day);
}
// Else, get the first day of the next month, then try the first step again (which should get us where we want to be)
else
{
// If the desired day is less than the current result day, it means our result day must be in the next month (it obviously can't be in the current)
// Get the next month by adding 1 to the current month mod 12 (so when we hit december, we go to january instead of trying to use a not real 13th month)
// If result.Month is November, 11%12 = 11; 11 + 1 = 12, which rolls us into December
// If result.Month is December, 12%12 = 0; 0 + 1 = 1, which rolls us into January
var month = (result.Month % 12) + 1;
// Get current/next year.
// Since we are adding 1 to the current month, we can assume if the previous month was 12 that we must be entering into January of next year
// Another way to do this would be to check if the new month is 1. It accomplishes the same thing but I chose 12 since it doesn't require an extra variable in the original code.
// Below can be translated as "If last result month is 12, use current year + 1, else, use current year"
var year = result.Month == 12 ? result.Year + 1 : result.Year;
// Set result to the start of the next month in the current/next year
result = new DateTime(year, month, 1);
}
}
// Return result
return result;
}
else
// If our desired day is invalid, just return Today. This can be an exception or something as well, just using Today fit my use case better.
return DateTime.Today;
}
Fun little puzzle. I generated 100 DateTimes which represent the starting day of each month, then checked each month to see if it had the date we want. It's lazy so we stop when we find a good one.
public DateTime FindNextDate(int dayOfMonth, DateTime today)
{
DateTime yesterday = today.AddDays(-1);
DateTime currentMonthStart = new DateTime(today.Year, today.Month, 1);
var query = Enumerable.Range(0, 100)
.Select(i => currentMonthStart.AddMonths(i))
.Select(monthStart => MakeDateOrDefault(
monthStart.Year, monthStart.Month, dayOfMonth,
yesterday)
.Where(date => today <= date)
.Take(1);
List<DateTime> results = query.ToList();
if (!results.Any())
{
throw new ArgumentOutOfRangeException(nameof(dayOfMonth))
}
return results.Single();
}
public DateTime MakeDateOrDefault(
int year, int month, int dayOfMonth,
DateTime defaultDate)
{
try
{
return new DateTime(year, month, dayOfMonth);
}
catch
{
return defaultDate;
}
}

Get current time and set a value in a combobox

I´m coding in C# and have done a Windows form with a few texteboxes and a combobox. I want to create a method that gets the current time and depending on the time sets the value in the combobox. In the combobox there are three values:
TimeZone 1
TimeZone 2
TimeZone 3
I have a code that gets the current time:
string CurrentTime = DateTime.Now.ToString("hh:mm");
And want to create a if statment (if its the best?) that gets the current time and sets the value in the combobox.
if the time are:
06:00 - 14:00 the combobox will get the value TimeZone 1
14:01 - 22:00 the combobox will get the value TimeZone 2
22:01 - 05:59 the combobox will get the value TimeZone 3
Any ideas of how to do this?
Literally what you said there in the question. Dont attempt to convert it to string and parse it again, it will just make your life harder. Here is a sample code logic
var now = DateTime.Now;
if (now.Hours >=6 && now.Hours <=14)
.....
else if (now.Hours > 14 && now.Hours < = 22)
.........
else
........
Try this
int hours = DateTime.Now.Hour;
if(hours >= 6 and hours <= 14)
{
combobox1.SelectedIndex = 0; //Assuming the TimeZone 1 is the first item.
}
else if(hours > 14 and hours <= 22)
{
combobox1.SelectedIndex = 1; //Assuming the TimeZone 2 is the second item.
}
else
{
combobox1.SelectedIndex = 2; //Assuming the TimeZone 3 is the third item.
}
string CurrentTime = DateTime.Now.ToString("hh:mm");
if(Convert.ToInt32(CurrentTime.Split(':')[0])>5||Convert.ToInt32(CurrentTime.Split(':')[0])<=14)
Combobox.SelectedValue="TimeZone 1";
else if(Convert.ToInt32(CurrentTime.Split(':')[0])>=14||Convert.ToInt32(CurrentTime.Split(':')[0])<=22)
Combobox.SelectedValue="TimeZone 2";
else if(Convert.ToInt32(CurrentTime.Split(':')[0])>=22||Convert.ToInt32(CurrentTime.Split(':')[0])<6)
Combobox.SelectedValue="TimeZone 3";

Categories

Resources