No more using multiple date time pickers to setup your time intervals. We are happy to introduce the brand new TimeSpanPicker control for WinForms applications. Learn all about the new control in the following article.
We've received multiple requests through the WinForms feedback portal to add a time span picker to the Telerik UI for WinForms suite and they have not been disregarded. In case you missed it, as of earlier this year, with the Telerik R1 2019 release, the new TimeSpanPicker control is available in the suite.
The RadTimeSpanPicker is a UI component that provides full control over selecting a specific time span and duration within certain ranges using the built-in components for days, hours, minutes, seconds and milliseconds.
Meet RadTimeSpanPicker
Imagine that we need to implement a flight booking system. First, we need to place a couple of DropDownLists for the from/to destinations, a DateTimePicker for picking the date of the flight and perhaps a filter for how long flight we will need. Here, in the last part, is where the RadTimeSpanPicker comes into play.
What we did above to configure the control is simply place it in the form and set its Format, and then we get the value the user entered from the Value property. We can also use the ValueChanged event to get notified when the Value property is changed. As simple as this.
this
.radTimeSpanPicker1.Format =
"'Under 'hh' hours'"
;
private
void
RadTimeSpanPicker1_ValueChanged(
object
sender, EventArgs e)
{
TimeSpan flightDuration =
this
.radTimeSpanPicker1.Value.Value;
// filter the flights
}
Other Useful Functionalities of the Control:
- Negative values – useful to show time overdue cases
- Binding – through the simple data binding
- Localization – make the control speak any language with the convenient localization provider
- EditMode – various edit modes are provided to capture the different use cases the control can be used in
- Mask – limit the user to just use the text box to modify the value
- Popup – limit the user to pick only predefined values from the pop-up
- Combined – give the user full flexibility
- Step properties – define the steps for each component, e.g. by 10min, by 2 hours, etc.
- ReadOnly – this lets you display time span information to the user without allowing editing, or allows you to enable/disable the editing capability per some business logic
- Null Values support – the control happily accepts null as Value, which is useful in data bound scenarios, in this case the NullText property can be used to show prompt text
- SpinButtons – a convenient feature that you can enable for users to change the value with the built in buttons in the text box
- Various events are at your leisure to get informed of value being changed (ValueChanging and ValueChanged), pop-up open/close (PopupOpened/Closed), as well as convenient extensibility point where we can plug in custom logic (the ComponentCreated and ComponentsCreated events of PopupContentElement) - more on this topic later
Structure
The control consists of two main elements: RadMaskedEditBoxElement and RadTimeSpanPickerContentElement.
RadMaskedEditBoxElement
RadMaskedEditBoxElement allows users to modify the value directly in the text box and at the same time validates it. The Format property specifies which portions of a time span value can be edited. The default format is “dd:hh:mm:ss.fff”
To add specific content to the format string you will need to enclose it with single quotes. Here is an example that shows this.
this
.radTimeSpanPicker1.Format =
"dd' days, 'hh' hours, 'mm' minutes, 'ss' seconds, 'fff' milliseconds'"
;
RadTimeSpanPickerContentElement
RadTimeSpanPickerContentElement is the main element of the pop-up and hosts a collection of components. Each component represents a different part of the TimeSpan object.
We provide five default time span part components, so you can easily set up the time intervals you wish to pick:
- DayTimeSpanPickerComponent
- HourTimeSpanPickerComponent
- MinuteTimeSpanPickerComponent
- SecondTimeSpanPickerComponent
- MillisecondTimeSpanPickerComponent.
Components are created each time the value of TimeSpanPickerElement Format property is changed, based on the desired format (for example: if the format is “dd:hh”, day and hour components will be created when the pop-up is opened).
Custom Components
We’ve provided a way to handle scenarios which require a custom time span as well.
For example, if you want the user to be able to pick one week intervals, you can easily implement it by creating a custom BaseTimeSpanPickerComponent and overriding its GetValueInTicks() and SetValue(TimeSpan value) methods. GetValueInTicks returns a TimeSpan value as ticks corresponding to the selected item from the UI component. SetValue is used to set the value of the component and choose which part of the TimeSpan value we want to use.
public
override
long
GetValueInTicks()
{
double
weeks =
this
.WeeksListTimeSpanPickerUIComponent.GetSelectedValue();
return
TimeSpan.FromDays(weeks * 7).Ticks;
}
public
override
void
SetValue(TimeSpan value)
{
double
weeks = value.Days / 7d;
this
.WeeksListTimeSpanPickerUIComponent.SetSelectedValue(weeks);
}
The BaseTimeSpanPickerComponent has a UI part, which is used to display the values to the end users. By default, we use RadListElement to list all available values. Now let’s add specific text to the values displayed in the list. We will override the CreateItemsSource method, which is used to create our items based on three properties: Minimum, Maximum and Step. In this case, we customize the displayed text and align it to the right. Here is what our custom UI component looks like:
public
class
WeeksListTimeSpanPickerUIComponent : ListTimeSpanPickerUIComponent
{
public
WeeksListTimeSpanPickerUIComponent(ITimeSpanPickerComponent owner) :
base
(owner)
{ }
protected
override
void
CreateItemsSource()
{
base
.CreateItemsSource();
foreach
(RadListDataItem item
in
this
.ListElement.Items)
{
item.Text = item.Value +
" weeks"
;
item.TextAlignment = ContentAlignment.MiddleRight;
}
}
public
double
GetSelectedValue()
{
return
this
.GetValue();
}
public
void
SetSelectedValue(
double
value)
{
this
.SetValue(value);
}
}
To include our custom component, we need to override the CreateVisualElement method of our WeekTimeSpanPickerComponent. We will also define our Minimum, Maximum and Step values and set the header text. The whole class looks like this:
public
class
WeekTimeSpanPickerComponent : BaseTimeSpanPickerComponent
{
public
WeekTimeSpanPickerComponent(ITimeSpanPickerContentElement owner) :
base
(owner)
{
this
.Minimum = 0;
this
.Maximum = 10;
this
.Step = 0.5;
this
.UpdateLocalization();
}
public
override
BaseTimeSpanPickerUIComponent CreateVisualElement()
{
return
new
WeeksListTimeSpanPickerUIComponent(
this
);
}
public
WeeksListTimeSpanPickerUIComponent WeeksListTimeSpanPickerUIComponent
{
get
{
return
this
.TimeSpanPickerUIComponent
as
WeeksListTimeSpanPickerUIComponent; }
}
public
override
long
GetValueInTicks()
{
double
weeks =
this
.WeeksListTimeSpanPickerUIComponent.GetSelectedValue();
return
TimeSpan.FromDays(weeks * 7).Ticks;
}
public
override
void
SetValue(TimeSpan value)
{
double
weeks = value.Days / 7d;
this
.WeeksListTimeSpanPickerUIComponent.SetSelectedValue(weeks);
}
public
override
void
UpdateLocalization()
{
this
.TimeSpanPickerUIComponent.HeaderText =
"Select Weeks"
;
}
}
The last step is to tell our RadTimeSpanPicker to use this newly created component. To achieve this, we need to subscribe to the ComponentsCreated event of PopupContentElement, where we will remove all default generated components and insert our custom one.
this
.radTimeSpanPicker1.PopupContentElement.ComponentsCreated +=
this
.PopupContentElement_ComponentsCreated;
private
void
PopupContentElement_ComponentsCreated(
object
sender, EventArgs e)
{
ITimeSpanPickerContentElement contentElement =
this
.radTimeSpanPicker1.PopupContentElement;
contentElement.Components.Clear();
contentElement.Components.Add(
new
WeekTimeSpanPickerComponent(contentElement));
}
In the end, we will add just a few more lines of code to show how you can add a new button next to the Close button, which will be used to reset the value of RadTimeSpanPicker.
TimeSpanPickerDoneButtonElement buttonPanel = (radTimeSpanPicker1.PopupContentElement
as
RadTimeSpanPickerContentElement).FooterPanel;
RadButtonElement clearButton =
new
RadButtonElement(
"Clear"
);
clearButton.Click += ClearButton_Click;
buttonPanel.LayoutPanel.Children.Add(clearButton);
And a code sample that shows how to access the panel with buttons and clear the value of RadTimeSpanPicker:
private
void
ClearButton_Click(
object
sender, EventArgs e)
{
RadButtonElement button = (RadButtonElement)sender;
TimeSpanPickerDoneButtonElement buttonPanel = button.FindAncestor<TimeSpanPickerDoneButtonElement>();
buttonPanel.Owner.SetValueAndClose(
null
);
}
Try It Out and Share Your Feedback
For more details about RadTimeSpanPicker, you can visit the online documentation and take a look at the demos. For any further feature or control requests, make sure to log them into the WinForms Feedback portal.
If you in search for a comprehensive WinForms UI toolkit for your current or upcoming desktop project and have not yet had the chance to explore Telerik UI for WinForms, you can find detailed information on the product page. You can also download a free 30-day trial to explore it in-depth and evaluate whether it will be a right fit for your application.