2012-03-14 16 views
6

Tengo un DateTimePicker que he puesto para mostrar sólo el mes y el año de la siguiente manera:¿Cómo puedo hacer que un selector de fecha y hora contenga siempre el último día del mes y solo el mes y el año?

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

Sin embargo, quiero que el valor de la fecha de ser siempre el último día del mes seleccionado, así que me puse el DateTime en caso ValueChanged usando:

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

el problema es, si tengo un mes como el de marzo seleccionado, y cambiar el mes a febrero mediante los botones arriba/abajo los controles, me sale el siguiente error antes de que pueda controlar el evento ValueChanged:

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

Esto es comprensible porque la fecha era el 31 de marzo y que está siendo cambiada al 31 de febrero, que es una fecha no válida. Sin embargo, quiero cambiarlo al 28 de febrero (o al 29 de febrero).

¿Cómo puedo lograrlo?

+2

esto es un error en DateTimePicker. Solución del problema está aquí: http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/69b10b5b-a034-426e-a045-2bed8a1637a3 –

+0

Debería poner esto como una respuesta, @HansPassant :) Me –

+0

ya contestado, no soy exigente con :) –

Respuesta

4

Muy extraño, traté de reproducir su problema, y ​​cuando cambio de marzo a febrero, mi control simplemente no muestra nada ... Tal vez tenemos diferentes versiones de frameworks, que manejan el mismo error de manera diferente.

De todos modos, una solución sería establecer el selector de fecha y hora para el primero de cada mes, y cuando se necesita el valor, sólo puede utilizar el código, ya que actualmente es:

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

Dado que nunca utilice el valor del día de su selector de dattime, puede simplemente configurarlo en 1, que siempre dará una fecha existente.

Esta solución me deja con una mala sensación alguna manera, dado que está utilizando una fecha que difiere de la fecha en que recibe de su mando - siempre una posible fuente de errores, la OMI. Recuerde poner comentarios en el código, lo que explica por qué están haciendo de esta manera ;-)

+0

Gracias @Treb.Ese es un enfoque interesante. Sin embargo, estoy de acuerdo en que es una posible fuente de errores, por lo que debo usarla con mucho cuidado. Si nadie sugiere algo mejor, probablemente tenga que hacer esto :-( –

+0

+1, buena solución al problema. –

+0

Intenté reemplazar 'PreProcessMessage' para capturar el mensaje antes de que se accediera al DateTime interno del control, pero no Tal suerte. Por cierto, durante las pruebas noté que el evento 'ValueChanged' siempre se disparaba dos veces: primero por el cambio iniciado a través del formulario, y segundo al llamar a' dateTimePicker1.Value = lastDayOfMonth; '... – Treb

2

probablemente usaría el día 1 del mes como Treb seleccionada, sino que se extienden DateTimePicker para que cuando se hizo esto:

MyDateTimePicker.Value

sería hacer algo como esto:

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

Buena sugerencia para extender DateTimePicker para ocultar la fea solución –

Cuestiones relacionadas