Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

DatePicker and hiding invalid dates

Status
Not open for further replies.

Merkaba

Programmer
Jun 14, 2005
69
US
Hi all!

I'm writing a reporting app where the user can select one date or a date range.

I put validation in so the user cannot select an end date before a start date and vice versa by manipulating the MaxDate and MinDate properties of two DatePicker Controls on a VB.NET 2.0 Windows App. The problem is that when using date ranges, if the user unwittingly selects the wrong end date, then tries to move the start date beyond it, they can click the calendar all they want, but nothing happens until they select a date before the end date.

Now, I know this is "unlikely" to happen, but I'm sure it will, and the people using it will complain. I was wondering if anyone knows how to shade/color/hide all dates > MaxDate and all dates < MinDate with the Framework's DatePicker control, or any other "user friendly" means to let the user know the date they are picking is not valid e.g. triggering a tooltip or something. And if you are sure you can not do this with the built-in control, please let me know so I can start making my own.

Thanks,

Merk
 
Hi Merk, I added some highlighting functionality to an extended datetimepicker a couple of weeks ago based on faq796-5566. I had to re-work some bits to ensure that the highlighting was consistent for value set, typed values and checkbox changes.

This is the code with just the highlighting bits added. You should be able to modify it so that it highlights based on a comparison to a date, but you might want to keep the options for future, historic etc.

Code:
Public Class DTP
	Inherits System.Windows.Forms.DateTimePicker

#Region " Windows Form Designer generated code "

    Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() call

    End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        components = New System.ComponentModel.Container()
    End Sub

#End Region


	Private myHighlightColour As System.Drawing.Color = Color.Yellow
	Private myHighlight As Highlights = Highlights.None
	Private myHighlighting As Boolean = False
	Private myLastValue As DateTime = Nothing
	Private myLastBackColour As Color = Color.White

	Public Enum Highlights
		Historic_Dates
		Current_Future_Dates
		None
	End Enum

#Region "Properties"
	Public Property Highlight() As Highlights
		Get
			Return myHighlight
		End Get
		Set(ByVal Value As Highlights)
			myHighlight = Value
			SetHighlight()
		End Set
	End Property
	Public Property HighlightColor() As System.Drawing.Color
		Get
			Return myHighlightColour
		End Get
		Set(ByVal Value As System.Drawing.Color)
			myHighlightColour = Value
			SetHighlight()
		End Set
	End Property
#End Region

#Region "Private Methods"
	Private Sub SetHighlight()
		myHighlighting = True
		Invalidate()		  'force redraw
	End Sub
	Protected Overrides Sub WndProc(ByRef m As Message)
		If m.Msg = CInt(&H14) Then		  'WM_ERASEBKGND
			If myHighlighting = True Then
				Dim col As Color
				If ShowCheckBox = True And Checked = False Then
					col = Color.White
				Else
					Select Case myHighlight
						Case Highlights.Current_Future_Dates
							If MyBase.Value.Date < DateTime.Now.Date Then
								col = Color.White
							Else
								col = myHighlightColour
							End If
						Case Highlights.Historic_Dates
							If MyBase.Value.Date < DateTime.Now.Date Then
								col = myHighlightColour
							Else
								col = Color.White
							End If
						Case Highlights.None
							col = Color.White
					End Select
				End If

				Dim g As Graphics = Graphics.FromHdc(m.WParam)
				g.FillRectangle(New SolidBrush(col), ClientRectangle)
				g.Dispose()
				myHighlighting = False
				myLastBackColour = col
				Return
			Else
				Dim g As Graphics = Graphics.FromHdc(m.WParam)
				g.FillRectangle(New SolidBrush(myLastBackColour), ClientRectangle)
				g.Dispose()
				Return
			End If
		End If
		MyBase.WndProc(m)
	End Sub
#End Region

#Region "EventHandlers"
	Private Sub DTP_ValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.ValueChanged
		If Value = myLastValue Then
			'assume check state change
			SetHighlight()
		End If
		myLastValue = Value
	End Sub

	Private Sub DTP_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Leave
		SetHighlight()
	End Sub
#End Region

End Class

The problem with controls validating and the error provider is that it is based on the assumption that you don't want the user to do anything else until the value is valid.

I think you can do your validation in the value_changed event handler and set the error on the errorprovider (I've not tried this). You can check if any controls in the form have a value in the provided error property as a means of validation before committing updates etc to the database.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top