Time Picker

While posting in the MSDN Forums of WPF, I received a lot of requests to create a TimePicker. So here it is finally, a simple yet extensible TimePicker. This control lets the user select a specific time by enter text in 3 textboxes (Hour, Minutes and Seconds). The user can also increment or decrement the time by pressing the Up and Down keys of the keyboard or even by clicking the up and down buttons that are supplied in the control. To make the user experience better when the user clicks the left or right key the focus of the textboxes changes, for example if the user is in the hours textbox and clicks the left key (if the caret index is at the end of the text) the minute text box will get focus. The Time Picker control also rounds the numbers that the user enter, for example if the user enters “88″ in the hours text box the Time Picker rounds this number to 23 (which is the highest number you can have for the hours textbox)

The Time Picker also supports ControlTemplates. There are 5 parts that you can use in your control template

->PART_Hours. This is the hours textbox you must supply this field so that the TimePicker can hook to the focus events and the text input events to change the time when text is enetered. When using this part the Time Picker will take care of adding the behaviour of focusing the next textbox when the left/right key is enetered etc..

-> PART_Minutes. This is the minutes textbox. This field is also needed for the Time Picker to change the time when text is entered. Again when using this field the time picker will hook to the events to get the behaviour mentioned above for the PART_Hours

-> PART_Seconds. This is the seconds textbox. This field is also needed for the Time Picker to change the time when text is entered. Again when using this field the time picker will hook to the events to get the behaviour mentioned above for the PART_Hours

->PART_IncreaseTime. This is a button that must be supplied to increment the time when the user click the button

->PART_Decrement. This is a button that must be supplied to decrement the time when the user click the button

Again this is a basic implementation of the TimePicker, nothing special but it is a start. I would really appreciate feedback so that I can enhance this control and maybe add some new features…

Feel free to download the code and play around with this control…

See also DatePicker
See alse DateTimePicker

Regards

TimePicker

DOWNLOAD SOURCE CODE

Masked TextBox

I found a new control for the AvalonControlsLibrary, the MaskedTextBox. I found this control while reading one of the best WPF books around from Matthew MacDonald.

The MaskedTextBox is a normal WPF textbox (in fact it inherits from the TextBox class) that formats the text entered by the user (and also strings set from the Text property programmatically). For example if you type 1234567890 into a masked textbox that has a U.S. telephone number mask, the text will be displayed as (123) 456-7890. To check out how you can create Masks have a look at this url.

To create this control I use the MaskTextProvider which is a .Net class. The MaskedTextProvider takes care of validating the string and also to format the text entered accordingly to the mask specified.

The MaskedTextBox has a Mask property which accepts a string. This string (and the mask property) is then used to create a MaskedTextProvider that can format the user input.

In order to intercept the user input, I override the OnPreviewTextInput method and apply the mask to the text that has been entered. As you can see this is 80% of the control’s code.

/// <summary>
/// override this method to replace the characters enetered with the mask
/// </summary>
/// <param name=”e”>Arguments for event</param>

protected override void OnPreviewTextInput(TextCompositionEventArgs e)
{
        
int position = SelectionStart;
        
MaskedTextProvider provider = MaskProvider;
        
if (position < Text.Length)
        {
                position = GetNextCharacterPosition(position);
               
if (Keyboard.IsKeyToggled(Key.Insert))
                {
                        
if (provider.Replace(e.Text, position))
                               position++;
                }
               
else
               
{
                        
if (provider.InsertAt(e.Text, position))
                              position++;
                 }
                 position = GetNextCharacterPosition(position);
         }
         RefreshText(provider, position);
         e.Handled =
true;
        
base.OnPreviewTextInput(e);
}

I also override the OnPreviewKeyDown method of the TextBox in order to handle special characters such as delete and backspace.Yet we have a problem! The problem is that if the user uses cut or paste the mask will not be applied until the next keystroke. So the workaround (described in the book) shows us how we can use CommandBinding to suppress these features. I really liked the idea because this shows us how commands can give us such power in our hands. So to suppress these features we have to do the following///<summary>
/// Default constructor
///</summary>
public MaskedTextBox()
{
           //cancel the paste and cut command
          
CommandBindings.Add(new CommandBinding(ApplicationCommands.Paste, null, CancelCommand));
           CommandBindings.Add(
new CommandBinding(ApplicationCommands.Cut, null, CancelCommand));
}
//cancel the command
private static void CancelCommand(object sender, CanExecuteRoutedEventArgs e)
{
           e.CanExecute =
false;
           e.Handled =
true;
}
 As you can see all you have to do is handle the command yourself and just set the CanExecute to false and Handled to true. Nice!Another problem is how we can force the Text property to apply the Mask when set programmatically. Since we only handle the OnPreviewTextInput this is not catered for. And here comes the FrameworkMetaData. Basically we can override the default meta data for the Text property and apply a CoerceValueCallback that apply the mask to the text./// <summary>
/// Static Constructor
/// </summary>
static MaskedTextBox()
{
             //override the meta data for the Text Proeprty of the textbox
           
FrameworkPropertyMetadata metaData = new FrameworkPropertyMetadata();
            metaData.CoerceValueCallback = ForceText;
           TextProperty.OverrideMetadata(
typeof(MaskedTextBox), metaData);
}
//force the text of the control to use the mask
private static object ForceText(DependencyObject sender, object value)
{
            
MaskedTextBox textBox = (MaskedTextBox) sender;
            
if (textBox.Mask != null)
            {
                     
MaskedTextProvider provider = new MaskedTextProvider(textBox.Mask);
                      provider.Set((
string) value);
                    
return provider.ToDisplayString();
            }
           else
          
{
                  
return value;
           }
}
 This shows us how powerful Dependency properties are. I was really excited about this one since it’s my first time to play around and override property meta data explicitly :)

And that’s basically it.Eventually I will implement a real MaskedTextBox by inheriting from the TextBoxBase but for now this will do the trick for developers that need this control.Hope you find this control useful.
Downlaod control demo and full source code

Virtualizing Treeview – aka TreeListBox v2.0

 As promised this weekend I re-wrote the TreeListBox (previous article posted here) control to support better virtualization… Basically I changed the whole idea… There are the same properties and same interface so whoever was using the old TreeListBox can just make an update and everything should work properly.

What was wrong in the old implementation was that I was generating the TreeListBoxItems instead of letting the VirtualizingStackPanel to generate them; the VirtualizingStackPanel was only not adding them to the logical tree! I realized this when I was profiling the component for memory.

In the new implementation I changed the whole concept. Basically now I generate a list of TreeListBoxInfo object from the HierarchalItemsSource specified by the user and set it to the ItemsSource of the TreeListBox.

The object transformation is something like the following

List of Persons  – > treelistbox.HierarchalItemsSource -> List of TreeListBoxInfo – > treelistBox.ItemsSource

Basically the TreeListBoxInfo is just an intermediate object that contains information such as the Level, Children and of course it stores the actual data item (in the example above the data item would be the person object)

Ok, so we have a flat list now but if I set the ItemsSource to have a list of TreeListBoxInfo this would mean that all DataTemplates for the TreeListBoxItem would not work because the user doesn’t know that the Items in the ItemsSource are of type TreeListBoxInfo! So here what we do is override the PrepareContainerForItemOverride method. This method allows us to change the object to set for the TreeListBoxItem and so we do the following…

/// <summary>
/// Prepares the new VirtualizingTreeViewItem with the actual business object
/// </summary>
/// <param name=”element”>The element (VirtualizingTreeViewItem) to apply the template</param>
/// <param name=”item”>The business object to set</param>
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
            TreeListBoxItem listItem = element as TreeListBoxItem;
            TreeListBoxInfo actualItem = item as TreeListBoxInfo;
            //prepares the item with the relative VirtualizingTreeViewInfo
            listItem.PrepareItem(actualItem);
            //pass the actual data item instead of the  VirtualizingTreeViewInfo
            base.PrepareContainerForItemOverride(element,   actualItem.DataItem);
}

As you can see we replace the item to prepare with the DataItem of the TreeListBoxInfo.

There is a lot of other things going on in the background such as registering to data binding events for children and finding the correct index where to push a new item in the list but I think that this is all you need to start working!

Please send me an email at marlongrech@gmail.com if you find any bugs or even if you have any suggestions.

Thanks for your support !

DOWNLOAD SOURCE HERE

Regards

[Last Update of Source Code - 06 October 2007 - fixed some memory leaks]

Virtualizing Treeview – aka TreeListBox

Before you start reading - I have a new version of the  TreeListBox available here

INTRO

Happy birthday to you, Happy birthday to you….. yahooooo today is my birthday!!! yes guys, it’s true today is my birthday and so yesterday I decided that I am going to give the developer side of me a birthday present!
I was thinking about this, when suddenly while having my daily bread (i.e reading the www.beacosta.com blog), I saw it ! the perfect birthday present, A Virtualizing TreeView Control!!!

UI Virtualization is really cool yet it is also complex. I had a chat with one of the best WPF developers I know Dr.WPF and he explained to me how complex it would be to have a VirtualizingStackPanel that understands hierarchies (have a look at the chat over here). As I already said this all started from the Beatriz Costa blog post, so I could just have used the same approach as beatriz (which by all means is good as the one I am using). But you know me, I like to build space shuttles (maybe even if it’s for nothing :) ).

So there I was with my pen and paper, packet of ciggarettes, mug of pure coffee and my beloved laptop(aka ‘marlon-csharp’)…
The Basic Idea
The basic idea is to have a listbox that understands hierarchies and populates a flat list instead of using the hierarchal list approach… something like the following

Actual tree structure

0
  child1 of 0
  child2 of 0
1
  child1 of 1
  child2 of 1

where here the data items are in 3 seperate collection >>
 1 for the main list (0, 1)
 1 for the children of 0(child1 of 0, child2 of 0)
 1 for the children of 1(child1 of 1, child2 of 1)
Flattened list
0child1 of 0
child2 of 0
1
child1 of 1
child2 of 1

on the other hand the flattened list would be one collection that contains all the items inside…

Basically the whole concept is to force the ItemsControl(which is our listbox) to stop from generating the Items by it self so that we can do it and set what ever values we want. If the ItemsControl thinks that it has a flat list BAMM you have it – Virtualization at last. Then it is just a matter of changing the look of the listbox to look like a treeview…

The Actual implementation

In order to implement the virtualization feature I simple extend the ListBox control with 2 new properties

ChildItemSourcePath -
This is basically a string that contains the name of the property exposing the collection of the children
Basically this is the Path you would enter for the binding of the HierarchalDataTemplate i.e

<HierarchalDataTemplate ItemsSource=”{Binding Path=Children}” …
transalates to
ChildItemSourcePath = “Children”

Basically this property is used so that by reflection we get the list that contains all children and populate them in the flattened list.

HierarchalItemsSource -
This property is just like the ItemsSource property yet when using the TreeListBox you must use this property for the data source, since this populates the ItemsSource by setting it to the internal flat list…
So if before you had this code in the tree view

ItemsSource = xList;
translate to
HierarchalItemsSource = xList;

Important – You should never use the ItemsSource property of the TreeListBox

—————————— 

Now the fun part begins……

int counter = 0;

foreach ( object item in newValue)
{   
       TreeListBoxItem
listItem = new  TreeListBoxItem (this, compositeChildCollection, 0);
    
       this
.PrepareContainerForItemInternal(listItem, item);    
     compositeChildCollection.Add(listItem);
   
     counter++;

}

this.ItemsSource = compositeChildCollection;
This code snippet basically is the whole concept. We prepare the items for the ItemsControl(i.e the listbox that we inherit from). In this way we can add the level property and we can also pass the compositeChildCollection which is out flat list so that the children can add themselves to this list. Now the children do practically the same thing


//get the current index of the current item from the flattened list. this index is then used to insert the child item for this item in the appropiate index

int currentIndex = parent.ItemContainerGenerator.IndexFromContainer(this);
//create the item yet this this the level is the current level + 1
TreeListBoxItem listItem = new TreeListBoxItem(parent, compositeDataItems, level + 1);
//ask the parent (which is the TreeListBox) to preapare the actual item

parent.PrepareContainerForItemInternal(listItem, item);
//add the new item in the Children collection of the current item
childTreeListBoxItems.Add(listItem);
//add the newly created item to the flat list (childTreeListBoxItems). this is a very important part. here we insert the item in the appropiate index of the flattened list
compositeDataItems.Insert(currentIndex + lastItemCreatedIndex, listItem);
lastItemCreatedIndex++;

 

And this is basically how we add item and child items in the TreeListBox… Now how can we remove them. This is relativly easy…
//we pass the item to delete to the remove method and this will automatically get the correct index for the itemand remove the item from the flattened list
compositeDataItems.Remove(item);

I hope you are still with me because basically this is it… You will for sure understand more if you have a look at the actual code! This is what I call the TreeListBox which is basically a normal Listbox that thinks its a tree view :)I hope you find this control useful, please send as many feedback as you can….I guess you all know my email, if not this is it marlongrech@gmail.com, contact me if you need anything…Now I think I need some sleep !!!Best Regards
Download Source Code
 

Update on the DatePicker

Hello guys,

Thanks to the comments submitted by Andreas I have updated the date picker with a new feture…

Basically now you can have a better and faster navigation when using the DatePicker by using the month selecter and year selecter. The month selecter is basically a combobox that you can use to navigate to other months, the year selecter is basically a textbox where one can enter a specific year….

I am now working on sorting of the listview for multi columns + I am also including a custom comparer that can improve performance for the sorting….(The source code is included in the AvaolonControlsLibrary download, yet I still need to work more on this feature)

Again thanks Andreas for your input… hope to get some more feedback…

Download Source + Demo

Regards

WPF DatePicker

[New Version of DatePicker available here] 

Here we are again…. this time it is a date picker control…. Yesterday, I couldn’t get any sleep so I decided to
build a sinple date picker control… It is very simple but I think it is very useful to have…
This control has a dependency property named CurrentlySelectedDate that gets updated when ever the use selects a
new date and that’s basically it… wow how nice… :)

One cool feature of this control is that it is restyleable… You can create a Control template to completly change

the look of the control… in the demo propeject I create a simple control template to show this feature… for

those of you who want to create a control template and use this control here are the PART names to use

“PART_MonthBack”, Type = ButtonBase, This button is used to navigate back to the previous month
“PART_MonthForward”, Type = ButtonBase, This button is used to navigate back to the previous month
“PART_CurrentlyViewedDate”, Type = ContentControl, This control is not need as such but basically this control
(if set) gets automatically databound to the current Month + Year in view
“PART_Dates”, Type = Selector This control gets populated with the days of the crrently

viewed month….

In the DatePicker I also create 2 converters one to calulcate width for the date cells(CellSizeConverter) and one to gray out the days that are shown in the Selector control but are not in the current month (IsCurrentMonthConverter). feel free to use these as well… to have a better idea how to use these converters have a look at the Generic.XAML file in the AvalonControlsLibrary project under the Themes folder….

Please contact me if you need any help with this control…

See alse DateTimePicker

Regards

Download Full Source code + Demo here…

DatePicker

WPF Range Slider Control

[New version fo Range Slider here] 

I know that you guys are waiting for the sorting of the DataGridView control, and I apologize for not completing it

yet. I needed a range slider, so I had to stop for 2 days to create this control… While I was at it I also

created a Magnifier (which is a normal slider but centered i.e when you release the thumb it goes back in the mid

point. more info below)…

The range slider is basically just like a normal slider control but you can select a range instead of a single

point. You can even drag the middle part(which is the selected range area) to move back and forward… It is very

easy to restyle this control, Basically there are 5 main properties that you can set

CenterThumbStyle – this is the area of the selected range (this is a thumb control)
LeftThumbStyle – this is the left slider thumb which is used to expand the range
RightThumbStyle – - this is the right slider thumb which is used to expand the range
LeftRepeatButtonStyle – this is the left edge of the slider (When click on the button you move the range selected

to the left)
RightRepeatButtonStyle – this is the right edge of the slider (When click on the button you move the range selected

to the right)

These properties all accept a style as parameter so that you can re style the control however you want.
Whenever the range is changed an event is raised providing you with the new range (RangeSelectionChanged).
A demo for the range slider + full source code is provided here…

The magnifier is a very simple control. Basically it is a normal slider yet, this slider goes back at the mid-

point(with a nice animation) when the user releases the slider thumb. When the user is holding the thumb to the

left or to the right a Magnified event is raised every x (where x is a TimeSpan set by the user). This can be used

to make a magnifing effect or even shrinking effect accordingly… have a look at the demo to get a better feel of

this control….

Any question, suggestions or comments please feel free to post. It is always nice to hear feedback…

Have fun coding….

Regards

P.S if you have some ideas or need a specific custom control please let me know so that I added to the backlog of

the controls to include in the AvalonControlLibrary

Source code and demo >>

AvalonControlsLibrary – Project in the PipeLine…

Hello Guys,

I just started working on a project … This project will consist of some WPF controls, in which I am planning to include a

DataGridView

  • enabling and disbaling columns
  • sorting (including support for property notifications)
  • auto generaion of columns(columns are formed automatically by lloking at the Type’s PropertyInfo, there will also be an attribute that you can use to specify in more detail the generation of the specific column)
  • exclude properties from auto generation
  • show properties that expose a collection with different behaviours
  • many other more cool features that I didn’t think of yet…

Range Slider

  • Slider with 2 thumbs
  • The Thumbs values can be represented in a DateTime
  • The two thumbs can be dragged to specify a different time range but with the same period

Any many other more….

All source code will be available on this site

Visit Project Page Here

Guys I would appreciate if you give feedback on other controls/features that you would like to see in this library…

Thanks for the support

WPF ROCKS!!!