public virtual void KeyDown(Control c, KeyEventArgs e)
{
Debug.Assert(c != null);
Debug.Assert(e != null);
// Validate incoming references
if (c == null) throw new ArgumentNullException("c");
if (e == null) throw new ArgumentNullException("e");
if (_viewManager != null)
{
switch (e.KeyCode)
{
case Keys.Tab:
_viewManager.KeyTab(e.Shift);
return;
}
}
// Get the current focus date
DateTime focusDate = (_months.FocusDay == null ? (_monthCalendar == null ? _months.Calendar.SelectionStart : _monthCalendar.SelectionStart) : _months.FocusDay.Value);
DateTime anchorDate = (_months.AnchorDay == null ? (_monthCalendar == null ? _months.Calendar.SelectionStart : _monthCalendar.SelectionStart) : _months.AnchorDay.Value);
// Use keyboard to modify the new focus date
switch (e.KeyCode)
{
case Keys.Left:
if (e.Control)
focusDate = focusDate.AddMonths(-1);
else
focusDate = focusDate.AddDays(-1);
break;
case Keys.Right:
if (e.Control)
focusDate = focusDate.AddMonths(1);
else
focusDate = focusDate.AddDays(1);
break;
case Keys.Up:
focusDate = focusDate.AddDays(-7);
break;
case Keys.Down:
focusDate = focusDate.AddDays(7);
break;
case Keys.Home:
if (e.Control)
{
focusDate = focusDate.AddMonths(-1);
focusDate = new DateTime(focusDate.Year, focusDate.Month, 1);
}
else
focusDate = new DateTime(focusDate.Year, focusDate.Month, 1);
break;
case Keys.End:
if (e.Control)
{
focusDate = focusDate.AddMonths(1);
focusDate = new DateTime(focusDate.Year, focusDate.Month, 1);
focusDate = focusDate.AddMonths(1).AddDays(-1);
}
else
{
focusDate = new DateTime(focusDate.Year, focusDate.Month, 1);
focusDate = focusDate.AddMonths(1).AddDays(-1);
}
break;
case Keys.PageUp:
if (e.Control)
focusDate = focusDate.AddMonths(-1 * _months.Months);
else
focusDate = focusDate.AddMonths(-1);
break;
case Keys.PageDown:
if (e.Control)
focusDate = focusDate.AddMonths(1 * _months.Months);
else
focusDate = focusDate.AddMonths(1);
break;
case Keys.Enter:
case Keys.Space:
if ((_monthCalendar != null) && _monthCalendar.AutoClose && (_months.Provider != null))
{
// Is the menu capable of being closed?
if (_months.Provider.ProviderCanCloseMenu)
{
// Ask the original context menu definition, if we can close
CancelEventArgs cea = new CancelEventArgs();
_months.Provider.OnClosing(cea);
if (!cea.Cancel)
{
// Close the menu from display and pass in the item clicked as the reason
_months.Provider.OnClose(new CloseReasonEventArgs(ToolStripDropDownCloseReason.Keyboard));
}
}
}
break;
}
// If the max selection count is 1 then always treat the new selection as the new focus
// day we have just calculated. If the shift key is not pressed then definitely treat as
// a single day selection.
if ((_months.Calendar.MaxSelectionCount == 1) || !e.Shift)
{
_months.AnchorDay = focusDate;
_months.FocusDay = focusDate;
_months.Calendar.SetSelectionRange(focusDate, focusDate);
if (_viewManager != null)
_needPaint(this, new NeedLayoutEventArgs(true));
}
else
{
DateTime startDate = _months.Calendar.SelectionStart;
DateTime endDate = _months.Calendar.SelectionEnd;
if (focusDate < anchorDate)
{
// Cannot extend selection beyond the max selection count
if ((anchorDate - focusDate).Days >= _months.Calendar.MaxSelectionCount)
focusDate = anchorDate.AddDays(-(_months.Calendar.MaxSelectionCount - 1));
startDate = focusDate;
endDate = anchorDate;
}
else if (focusDate > anchorDate)
{
// Cannot extend selection beyond the max selection count
if ((focusDate - anchorDate).Days >= _months.Calendar.MaxSelectionCount)
focusDate = anchorDate.AddDays(_months.Calendar.MaxSelectionCount - 1);
startDate = anchorDate;
endDate = focusDate;
}
_months.AnchorDay = anchorDate;
_months.FocusDay = focusDate;
_months.Calendar.SetSelectionRange(startDate, endDate);
if (_viewManager != null)
_needPaint(this, new NeedLayoutEventArgs(true));
}
}