Question

In a WinForms (3.5) application there is form with a monthCalendar control.

The calendar control has a calendarDimension of 3 columns by 1 row. This means that it currently shows June, July, August of 2010.

Is it possible to have the calendar to show April, May, June of 2010 instead? My dataset doesn't have any future dates so the date selection will be for current or older dates.

Was it helpful?

Solution

You can use the following line of code to set the MonthCalendar's MaxDate property to current date in the form's load event.

monthCalendar1.MaxDate = DateTime.Now;

OTHER TIPS

If you set the MonthCalendar's MaxDate to the current date, the month calendar will only show - and thus allow selection of - dates on or earlier than the current date.

To force the current month to the right I used Pavan's idea, but I added a timer to reset MaxDate after opening on the calendar control. Now I can scroll into the future after loading the control.

public partial class Form1 : Form
{
   private DateTime _initialDateTime = DateTime.Now;

   public Form1()
   {
     InitializeComponent();
     // remember the default MAX date
     _initialDateTime = monthCalendar1.MaxDate;
     // set max date to NOW to force current month to right side
     monthCalendar1.MaxDate = DateTime.Now;
     // enable a timer to restore initial default date to enable scrolling into the future
     timer1.Start();
   }

   private void timer1_Tick(object sender, EventArgs e)
   {
     Timer timer = sender as Timer;
     if (timer != null)
     {
        // enable scrolling to the future
        monthCalendar1.MaxDate = _initialDateTime;
        // stop the timer...
        timer.Stop();
     }
   }
}

I discovered that manipulating the MonthCalendar to "scroll" to the desired range needs to occur After the MonthCalendar is self-aware.

After the MonthCalendar is self-aware (after your program is done initializing and displaying it, if you execute MyMonthCalendar.SetSelectionRange(startDate,endDate) you can scroll the calendar by making the startDate outside of the currently displayed months. For example, if I am displaying 8 months as 2 columns by 4 rows, then MyMonthCalendar.SetSelectionRange(DateTime.Now.AddMonths(+6),DateTime.Now.AddMonths(+6)); will scroll the MonthCalendar to show DateTime.Now in the Month[col1,row[0]] (top row, right column).

The catch is that the MonthCalendar.SetSelectionRange() does not take affect until AFTER the MonthCalendar is displayed and can "scroll" After it has exited its initialization thread. This is why the Timer method described by others works.

I don't know about earlier .NET versions, but in .NET 4.6, you don't need to modify MinDate or MaxDate to scroll the MonthCalendar.

Instead of using a Timer component and event, I suggest trying the MonthCalendar.Layout event.

public MyForm()
{
  // Standard design time component initialization
  InitializeComponent();

  // enable the MonthCalendar's Layout event handler
  this.MyMonthCalendar.Layout += MyMonthCalendar_Layout;
}

/// MonthCalendar Layout Event Handler
private void MyMonthCalendar_Layout;(object sender, LayoutEventArgs e)
{
  // disable this event handler because we only need to do it one time
  this.MyMonthCalendar.Layout -= MyMonthCalendar_Layout;

  // initialize the MonthCalendar so its months are aligned like we want them to be
  // To show a calendar with only April, May, and June 2010 do this
  this.MyMonthCalendar.SetSelectionRange(new DateTime(2010, 4, 1), new DateTime(2010, 6, 30));

  // MyMonthCalendar.TodayDate can be any date you want
  // However, MyMonthCalendar.SetDate should be within the SelectionRange or you might scroll the calendar
  this.MyMonthCalendar.SetDate(new DateTime(2010, 6, 30));      
}

enter image description here

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top