Как сделать так, чтобы указатель времени даты всегда содержал последний день месяца, показывая только месяц и год? - PullRequest
7 голосов
/ 14 марта 2012

У меня есть DateTimePicker, который я настроил так, чтобы показывать только месяц и год следующим образом:

myDateTimePicker.Format = DateTimePickerFormat.Custom;
myDateTimePicker.CustomFormat = "MMMM yyyy";
myDateTimePicker.ShowUpDown = true;

Однако я хочу, чтобы значением даты всегда был последний день выбранного месяца, поэтому я установил DateTime в событии ValueChanged, используя:

DateTime selectedDate = myDateTimePicker.Value;
DateTime lastDayOfMonth = new DateTime(
    selectedDate.Year,
    selectedDate.Month,
    DateTime.DaysInMonth(selectedDate.Year, selectedDate.Month));
myDateTimePicker.Value = lastDayOfMonth;

Проблема в том, что если у меня выбран месяц, подобный марту, и я меняю месяц на февраль с помощью элементов управления вверх / вниз, я получаю следующую ошибку перед обработкой события ValueChanged:

ArgumentOutOfRangeException was unhandled
Year, Month, and Day parameters describe an un-representable DateTime.

Это понятно, потому что дата была 31 марта, и она меняется на 31 февраля, которая является недопустимой датой. Однако я хочу изменить его на 28 февраля (или 29 февраля).

Как мне этого добиться?

Ответы [ 2 ]

4 голосов
/ 14 марта 2012

Очень странно, я пытался воспроизвести вашу проблему, и когда я переключаюсь с марта на февраль, мой элемент управления просто ничего не отображает ... Возможно, у нас разные версии фреймворка, которые по-разному обрабатывают одну и ту же ошибку.

В любом случае, одним из решений было бы установить указатель даты и времени на первое число каждого месяца, и когда вам нужно это значение, вы можете просто использовать свой код, как он есть на данный момент:

DateTime lastDayOfMonth = new DateTime(
    selectedDate.Year, 
    selectedDate.Month, 
    DateTime.DaysInMonth(selectedDate.Year, selectedDate.Month)); 

Поскольку выникогда не используйте значение дня в вашем датере, вы можете просто установить его на 1, что всегда даст существующую дату.

Это решение почему-то оставляет у меня плохое предчувствие, так как вы используете дату, которая отличаетсяс даты, которую вы получаете от вашего контроля - всегда возможный источник ошибок, ИМО.Не забудьте добавлять комментарии в ваш код, объясняя, почему вы делаете это таким образом; -)

2 голосов
/ 14 марта 2012

Я бы, вероятно, использовал 1-е число месяца как Treb Selected, но расширил DateTimePicker, чтобы при этом:

MyDateTimePicker.Value

он делал бы что-то вроде этого1006 *

get{
return value.addMonths(1).addDays(-1)
}
...