Jasema – The XAMLPadX plugin for building Path Geometry

[Jasema v2 has been released]

XAMLPadX v3 is out ! I love XAMLPadX, for me it is one of the best tools to have when developing WPF applications. One of the best features of XAMLPadX v3 is that you can build your own plugins… cool !! So basically we can be part of it!

Lately I was creating some simple paths yet it took me ages to build them because I was building them manually by hand. While creating the geometry for these paths I noticed that creating a tool to build these paths would be very easy… All you have to do is record where the mouse pointer is and put it in the Data property of the Path (for more info on how to build path geometry click here). So I decided to build a tool that I can use to build these Paths more efficiently…

jasema.jpg

The tool can be integrated as a XAMLPadX plugin and also run as a standalone application. Jasema is very simplistic and only caters for straight line paths (it is only v1, I am just testing the idea) yet in the near future I will add more functionality for it in order to support much more complex Paths.

You can generate paths by click on the drawing surface provided in the tool. When a point is created the point is shown as a small dot. If you click on the dot that point will be removed from the path geometry. Another interesting and helpful feature in Jasema is the Layout Grid. The layout grid is a simple grid that is drawn on the background of the drawing surface so that you have more guidance while painting the path that you want. You can also make the grid larger or small as you prefer by using the slider menu that is provided in the tool bar.

Why did I call this tool Jasema?

well “Jas” are the first 3 letters of my daughter’s name – Jasmine
“Ema” is the name of my wife….
concatenate them …. string toolName = “Jas”+”ema”;
There you have it “Jasema”

To install this tool as a XAMLPadX plugin you will need to

First of all install XAMLPadX v3
– Create a folder called “Jasema” under “C:\Program Files\XamlPadX\Addins” (assuming that XAMLPadX v3 is installed in that directory)
– Copy the Jasema.dll and paste it in the folder that you have just created
– Thats’s it ! Now when you open XAMLPadX and click on Plugins >> More Plugins, Jasema will appear in the list and you can select it…

To run Jasema as a standalone application you can do so, by starting up the JasemaApp.exe…

Again I want to point out that this is just the start…. I have loads of ideas on how to improve this tool such as supporting more complex paths etc… I am waiting to see the feedback on this tool because at the end of the day it is just an idea, now it is up to us to expand this idea into a handy tool :)

PLEASE SEND FEEDBACK….

Download Full Source Code
Download DLL and Executable

Avalon Controls Library on CodePlex

Hi all,

I am pleased to announce that the AvalonControlsLibrary  has been uploaded on CodePlex. I am looking forward to see this project evolve more and more in the near future.

Looking forward to see more suggestions for this library so that together we can make this library grow ….

Visit the CodePlex homw page here 

Thanks for all the help and support

Rating Selector

Hello …

It’s been a while now since my last update on the blog. Currently I have been really busy, work family… You know the so called life… :)

Some friends from Alambic asked me if I can create a Rating control for the AvalonControlsLibrary. A request for a control is always exciting for myself… So here it is a brand new control that you can go ahead and use…

The contol is very simple, you specify a MinRating (by default 0) and a MaxRating(by default 5) and the control will go ahead and create a list of Stars(this is the default look of the control, you can change this with a control template). The user can then click on one of the Rate Items(the star) and select a Rating. The Rating selected can be read from a property RatingSelected. The RatingSelected is a dependency property so you can bind to it and get notified when the value changes. I also added the IsReadOnly property so that you can specify that the control is readonly and the user cannot change the control. There are also 2 other important properties RateItemColor and RateItemHoverColor. By setting these properties you can change the color for the rate items (the stars by default)

Now lets dig into the implementation of the control… Believe it or not this contol is just an ItemsControl… You don’t beleive me? check this link to see even crazier ItemsControl. Basically I create a list of RatingSelectorItems ranging from the MinRating to the MaxRating and add them in the ItemsSource of the control. The RatingSelectorItem has a RateValue property that is the Rate that the item represents. The RatingSelectorItem also has a IsSelected property that is set to true when the user selects a rating that is bigger or equal to the rate of the item.

The Rate selected is triggered via a Command (more details on command found here) called SelectRating. This command also has a constraint so that it can be executed only if the IsReadOnly property of the RatingSelector is false.

The demo for the control contains different control templates for the control. It shows how you can show different objects for the Rate Items and aslo how to change the orientation of the control (which comes for free since the control is an ItemsControl)

Go Ahead, download the control and send me feedback… Any bugs or problems, feel free to send me and email…

Rating Control

Download Source Code and Demo

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