Introduction

I couldn't put up with the standard time part of the DateTimePicker any longer. I wanted an easy to use date dropdown and a non-existent time dropdown. First, I made the gTimePickerCntrl to pick the time in a couple of clicks using a clock-like interface. Second, I needed a dropdown control to contain it. Third, the developer in me needed the extra design-time support.

After making the gTimePicker, I realized I needed a nullable DateTimePicker to go with it. Now, I have added the gDateTimePicker and added a nullable feature to the gTimePicker.

How to Use the gTimePickerCtrl

Very simple - Click a number in the inner ring for the hour. Click a number from the outer ring for minutes.

Control Properties

Here is a list of the primary properties:

Public Property Time() As String

Get or set the time value

Public Property TimeAMPM() As eTimeAMPM

Get or set the AM PM value

Public Property Hr24() As Boolean

Get or set the time as 12 or 24 hour

Public Property TrueHour() As Boolean

Get or set if the hour hand shows true clock position or stays pointing at the chosen hour regardless of the minute

Public Property TimeColors() As TimeColors

Get or set the color scheme for the control

Paint

At first, I had a background image of the clock face and drew the hands on top of it, but then I got stuck with that image's color. To make it more dynamic, I drew the frames using a simple PathGradientBrush to create the illusion of a 3D frame.

Control Properties

The matching gTimePickerCntrl properties get or set the corresponding TimePickerCntrl values. Here is a list of the additional properties:

Public Property TimeAMPM() As eTimeAMPM

Get or set the AM PM value

Public Property Hr24() As Boolean

Get or set the time as 12 or 24 hour

Public Property TrueHour() As Boolean

Get or set if the hour hand shows true clock position or stays pointing at the chosen hour regardless of the minute

Public Property TimeColors() As TimeColors

Get or set the color scheme for the control

Public Property TextBackColor() As Color

Get or set the backcolor for the text

Public Property TextForeColor() As Color

Get or set the forecolor for the text

Public Property TextAlign() As HorizontalAlignment

Get or set the horizontal alignment for the text

Public Property TextFont() As Font

Get or set the textbox font

Public Property ButtonForeColor() As Color

Get or set the color of the arrow on the dropdown button

Public Property ButtonBackColor() As Color

Get or set the base color of the dropdown button

Public Property ButtonHighlight() As Color

Get or set the highlight color of the dropdown button

Public Property ButtonBorder() As Color

Get or set the border color of the dropdown button

Public Property NullText() As String

Text to display when NULL

Public Property NullTextInFront() As Boolean

Should the NULL text appear in front of the hatch fill

Public Property NullTextColor() As Color

Color for the NULL text

Public Property NullHatchStyle() As HatchStyle

Chooses the HatchStyle

Public Property NullColorA() As Color

Color A for the HatchStyle

Public Property NullColorB() As Color

Color B for the HatchStyle

Public Property NullAlpha() As Integer

Alpha value for HatchStyle so you can see the NULL text through it

Methods

Public Function ToStringAMPM() As String

Returns _Time & " " & _TimeAMPM.ToString

Public Function ToDate() As DateTime

Returns CDate(_Time & " " & _TimeAMPM.ToString)

Public Function Hour() As Integer

Returns the hour

Public Function Minutes() As Integer

Returns the minutes

Public Sub TimeInMinutes(minutes as Integer)

Sets the time using minutes (example: 1100 minutes equals 06:20 PM)

Mouse Events

In the MouseDown event, check if the popup is open or closed, and Show or Hide it accordingly. One problem is when clicking the button to close the ToolStripDropDown, it loses focus, causing it to close automatically, so when the click gets through, it reopens. To get around this, check if the pointer is over the button and set IsPopupOpen = False in the popup_Closing event.

KeyPress Event

For a quick adjustment, press the Up or Down arrow keys to adjust the minutes and Shift-Up or Shift-Down to adjust the hours.

Nullable TextBox

I wanted the gTimePicker to match the gDataTimePicker visually when nulled, so I extended the standard TextBox, added the null properties, and overrode the WndProc Sub to paint the null properties when Text.Length = 0.

Design Time Extras

Since I already have an article on UITypeEditors, go here for a more detailed explanation of any design time features: UITypeEditorsDemo[^].

I created a separate class for the color scheme so I could manipulate it easier in the editors. Class TimeColorConverter: Inherits ExpandableObjectConverter allows editing of individual colors directly in the property grid. Class TimeUIEditor : Inherits UITypeEditor gives a dropdown for the Time property in the property grid.

Class TimeColorsUIEditor : Inherits UITypeEditor opens a dialog to edit all the colors with a preview by pressing the button in the property grid.

gDateTimePicker

It looks like a DateTimePicker because it Inherits System.Windows.Forms.DateTimePicker. There are quite a few nullable DateTimePickers out there, but I wanted something a little different (as usual), so here it is. Everything functions normally, except you can set the value to Nothing. Setting DateTimePicker.Value = Nothing will cause an error normally. I started by shadowing the Value property of the DateTimePicker control and using the DateTime.MinValue switcheroo method I had seen in some other controls, but that just led to a lot of synchronization problems, especially when I tried to bind the control.

Time to start over. The DateTimePicker has three properties I need to manipulate: Value, Format, and CustomFormat. The trick to simulating the Null is to set the Format to Custom and CustomFormat = " " so it displays a space no matter what the value is. This visually looks like a NULL, but the value isn't truly a NULL, especially if you want to bind it. First, I made these properties hidden:

The only additional extra I wanted was to still be able to have the date dropdown in the propertygrid and still be able to NULL it. The Type Nullable(Of DateTime) doesn't have its own editor, so I made the NullableDateTimeTypeEditor and NullableDateTimeDropDown for it.

Altering the null properties allows you to change the appearance of the control when it is Null. Change the Fill and/or add a text message to appear.

Share

About the Author

I first got hooked on programing with the TI994A. After it finally lost all support I reluctantly moved to the Apple IIe. Thank You BeagleBros for getting me through. I wrote programs for my Scuba buisness during this time. Currently I am a Database manager and software developer. I started with VBA and VB6 and now having fun with VB.NET/WPF/C#...

I have an idea for something new, if you are up to it.
There are times when you have a single form with some selection on the left side of the window (a panel) that displays different panels on the right side depending upon the selection on the left side of the panel. This is easy to accomplish with multiple panel controls, each laid out specifically for the task.

Example:

with a database, say you click a node in a tree to create a connection string, the panel dealing with connection string creation appears on the right. Then you have a node of queries or tables and choose to create a query--the query panel appears.

The problem is that these panels are HARD to work with at design time. It would be super if there was some tab like control or something such that you could have one panel per tab, but that would only appear during design time to allow you to make changes to the panel object in question without having to move them around. This inadvertently often place panel1 into panel 2 and such and causes problems. In the end I'd still like to say, show panel 1 or panel 2, but not have the tab or whatever designtime mechanism show up.

I thought if anyone could see the use in this and be able to accomplish it, it would be you. I understand if you are too busy, but thought I'd give you the idea.

Yes that is possible. I actually just tested it I have an extended Tab Control I made because the MS one messes up when the tabs are on the sides, plus I wanted control over the colors of the tabs. It is one of my first controls and is not fully checked, but I do use it alot and havn't had any issues yet. Anyway I just looked at it and added a check for the design mode and bypassed drawing the tabs during runtime so only the pages show. In design time the tabs show. The only thing left would be to trap the mouse in run time to not switch the pages.

Oh another way you could acomplish this without a special control is to put the panels into a FlowLayoutPanel. In design mode just scroll to the one you want to edit. In run time just make the visibility of the one you want to see to true and the others false.

It has been useful for a number of purposes so far. I have used it for this purpose in a couple of projects. I had a set of RadioButtons that would display the correct Panel of controls to choose from. The FlowLayoutPanel control has the same backcolor as the form so no one knows it is even there.

I know, I write programs too. Yours looks great. One man said, "fool proofing is hard be cause fools are so inventive." Now I don't like calling anyone a fool, but it is comical and does represent to problem faced by developers well.