January 2008 - Posts

Silverlight 1.0 Fire Starter

Silverlight, the promise of a richer web based user interface!

Nobody can deny that Silverlight is a big part of the future direction of a richer web envisioned by Microsoft. As with the WPF bootcamp, Microsoft has released the videos of there 1-day event called Silverlight 1.0 Fire Starter. All 8 the tracks are available for viewing or downloading from the MIX University website. These videos provide a solid background of how to develop a silverlight 1.0 application. It is well worth the download!

The tracks are:

  • A Introduction to Silverlight by Mithun Dhar
  • Getting started programming Silverlight by Jesse Liberty
  • Workflow of silverlight with expression and visual studio by Arturo Toledo
  • Silverlight XAML by Laurence Moroney
  • A development story by Adam Kinney
  • Media, markers and more by Ernie Booth
  • Popfly and silverlight by Adam Nathan
  • Silverlight in the future by Ernie Booth

Hopefully we will see the same for Silverlight 2.0 soon!!!

Posted by rudi | 1 comment(s)

DataModel-View-ViewModel used in a WPF Application

The last week I have been researching patterns & practices! MVP, MVC, DM-V-VM was all to confusing for me...

[EDIT] Josh has e xcellent presentation (with code) about using MVC pattern in WPF (Available here

I found a excellent series by Dan Carevier about using the DM-V-VM pattern in WPF and decided to try and use it!

Lets start by defining why I wanted to use it. DM-V-VM basically offered 2 advantages that I wanted to achieve:

1) Asynchronously retrieve data from my data source. I have a large data set and wanted my application to be able to retrieve this data in the background.

2) Separating the UI from the data source or in DM-V-VM terms: Separating the DataModel (Data Source) from the View (UI). The benefit of doing this is that the UI is completely skinnable! Different views can be loaded dynamically changing the appearance of the application completely! In MVC/MVP terms, this separation also allows easily changing from technology by just implementing a new View (IE. moving from WinForms to WPF, etc).

To demo the DM-V-VM pattern I needed a large data set. Since many people are Facebook-aholics (with 400+ friends) it seemed like the perfect data set. Lets start with the DataModel.

The DataModel's main purpose is to expose the data in a way that is easily consumable by a WPF application. In WPF terms, this means implementing INotifyCollectionChanged and INotifyPropertyChanged! My DataModel is very similar to the one described by Dan Carevier, The only small change is that I also implemented a debug check to verify that when a property changed notification is raised, that the property actually exists (Taken from Josh Smith's BindableObject). In his article Josh also mention a method of reducing managed heap fragmentation by caching the PropertyChangedArgs. I did not implement this in my example thou!

Here is the code for my base DataModel:

public class DataModelBase : INotifyPropertyChanged
{
    protected Dispatcher _dispatcher;

    public DataModelBase()
    {
        _dispatcher = Dispatcher.CurrentDispatcher;
    }

    private ModelState _state;
    public ModelState State
    {
        get
        {
            VerifyCalledOnUIThread();
            return _state;
        }
        set
        {
            VerifyCalledOnUIThread();
            if (value != _state)
            {
                _state = value;
                SendPropertyChanged("State");
            }
        }
    }

    [Conditional("Debug")]
    protected void VerifyCalledOnUIThread()
    {
        Debug.Assert(Dispatcher.CurrentDispatcher == _dispatcher, "Call must be made on UI thread.");
    }

    private PropertyChangedEventHandler _propertyChangedEvent;
    public event PropertyChangedEventHandler PropertyChanged
    {
        add
        {
            VerifyCalledOnUIThread();
            _propertyChangedEvent += value;
        }
        remove
        {
            VerifyCalledOnUIThread();
            _propertyChangedEvent -= value;
        }
    }

    [Conditional("DEBUG")]
    private void VerifyProperty(string propertyName)
    {
        Type type = this.GetType();
        PropertyInfo propInfo = type.GetProperty(propertyName);
        if (propInfo == null)
        {
            Debug.Fail("VerifyProperty");
        }
    }

    protected void SendPropertyChanged(string propertyName)
    {
        VerifyProperty(propertyName);

        VerifyCalledOnUIThread();
        if (_propertyChangedEvent != null)
        {
            _propertyChangedEvent(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

This is a very basic base class. I define a state for the data (Fetching,  Invalid or Active). There is also a check to ensure that the data is only read from the UI thread. The last part of this class handles the notification when properties change.

Next, lets implement a FriendDataModel. The purpose of the FriendDataModel is to retrieve the User class from the Facebook service asynchronously.

class FriendDataModel : DataModelBase
{
    private FacebookService _service;
    private string _ID;

    private User _friend;
    public User Friend
    {
        get
        {
            VerifyCalledOnUIThread();
            return _friend;
        }
        set
        {
            VerifyCalledOnUIThread();
            _friend = value;
            SendPropertyChanged("Friend");
        }
    }

    public FriendDataModel(string ID, FacebookService service)
    {
        _ID = ID;
        _service = service;

        State = ModelState.Fetching;
        if (!ThreadPool.QueueUserWorkItem(new WaitCallback(FetchFriend)))
        {
            State = ModelState.Invalid;
        }
    }

    private void FetchFriend(object state)
    {
        User u = _service.GetUserInfo(_ID)[0];
        
        if ( u != null )
        {
            this._dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle,
                new ThreadStart(delegate
                {
                    this.Friend = u;
                    this.State = ModelState.Active;
                }));
        }
        else
        {
            this._dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle,
                new ThreadStart(delegate
                {
                    this.State = ModelState.Invalid;
                }));
        }
    }
}

Ok, lets examine this class. The FriendDataModel takes the ID of the friend to be retrieved and the instance of the Facebook service. The constructor sets the state to fetching and the queue a user work item. Now the FetchFriend can asynchronously get the User object for the provided ID. Once the User object has been retrieved, the FetchFriend updates it's status by using the dispatcher.

Now we have a working FriendDataModel, lets test it. I created a very basic WPF application with only a Listbox named FriendsListBox. The magic now happens in the code behind file.

I create a instance of the Facebook service and set my ApplicationKey and Secret (For more detail on how to setup the Facebook service, have a look at this CodeProject article).

Now we can call the lightweight GetFriendsIds that returns a collection of Ids for all your friends (Do not call GetFriends as this will return all the detail for all your friends, this takes forever to load). All that is left now is to iterate through this collection and add a FriendDataModel for each of these ids to a ObservableCollection and bind the ListBox to this! Here is the code:

void Window1_Loaded(object sender, RoutedEventArgs e)
{
    s.ApplicationKey = "[YOUR APPLICATION KEY]";
    s.Secret = "[YOUR SECRET]";
    s.IsDesktopApplication = true;

    ObservableCollection<FriendDataModel> friendsDM = new ObservableCollection<FriendDataModel>();
    FriendsListBox.ItemsSource = friendsDM;

    Collection<string> friends = s.GetFriendIds();
    foreach (string id in friends)
    {
        friendsDM.Add(new FriendDataModel(id, s));
    }
}

This will start to collect friends details once you have logged into Facebook. Add the following DataTemplate to see how the states of all your friends gets updated

        <DataTemplate DataType="{x:Type local:FriendDataModel}">
            <StackPanel>
                <TextBlock Text="{Binding Friend.FirstName}"/>
                <TextBlock Text="{Binding Friend.LastName}"/>
                <TextBlock Text="{Binding State}" />
            </StackPanel>
        </DataTemplate>

This is all for the first part...

I will go into more detail about the ViewModel and View in the next article.

If you ever tried to write a desktop facebook application you would know that it takes time to load all your friends. This DataModel speed this up by returning immediately to the UI and then doing all the work (Retrieving Friend details) in the background.

For more WPF related resource, check out the WPF Rock Star list

Posted by rudi | 1 comment(s)
Filed under:

Under the hood: Attached Properties

I recently started playing round with attached properties. They are very useful. I wrote 2 CodeProject articles on how to effectively use them.

Glass Effect

Drag & Drop

The code for these articles is available for download here

To understand how attached properties work, we first have to grasp how DependencyObject and DependancyProperty work! I will explain the basics by dissecting a very basic application. I wrote a small application that has a StackPanel and in the stack panel are 2 buttons. The first button just has text inside and the other has a small image. Let's start off by defining what a visual tree is. The visual tree is exactly (or almost) what it sounds like. It's a tree of visual elements and how they are related. Here is a simplified visual tree for our application.

 

PS. Use mole to see a more detailed visual tree

 [EDIT] Adam Nathan's book WPF unleashed has a excellent chapter about Visual and Logical trees. I found a link where you can download this chapter

Next, most controls are derived from DependencyObject. DependencyObject functions as a cup where you can store all your DependencyProperties for the selected control (Similar to a dictionary). It is important to realize that each control has its own DependencyObject that holds all the DependancyProperties for this control's instance.

This is also where the magic happens... If you look at the visual tree, then you will soon realize that a DependancyObject also stores all the properties for the items "above" it in the visual tree. Ok, this is a huge concept to grasp!!! Look at the provided Visual Tree. It is important to notice that although Window has a DependancyPropety called FontSize, the StackPanel doesn't! But because the DependancyObject "inherits" everything above it, the StackPanel also knows what the items above its FontSize are!!! Well, that sounds amazing, prove it... Ok, let's start by setting the windows FontSize to something like.

FontSize = 32;

If you now run this application, all the buttons size will also change to 32 because Window is above all the controls, all the items underneath it knows its FontSize!!! Ok, Button has a FontSize but what about the StackPanel? Let's have a look at the StackPanel

double fontSize = (double)rootSP.GetValue(Control.FontSizeProperty);

This should now ask the rootSP's "cup" if it is holding any FontSizeProperty values... This should return 32. Ok, so this proves that although StackPanel has no property called FontSize, it can hold such a value if it has an item above it in the visual tree with such a property! OK, how does this relate to Attached Properties? Attached Properties are DependancyProperties, they are just register differently.

Let's look at how regular DependancyProperty works

Register a DependencyProperty object (i.e. FontSizeProperty) and then define a public property (ie. FontSize) that use the standard CLR properties get and set to call GetValue and SetValue on itself!

Attached properties works similar, register a DependencyProperty object (i.e. FontSizeProperty) with RegisterAttach and then define static Get<PropertyName> and Set<PropertyName> (ie. SetFontSize and GetFontSize). The Get and Set gets passed as a parameter the element it needs to set the DependencyProperty on!

OK, but how does this work? Imagine you are designing a layout system. In the old days you needed to have each control expose a Left & Top property. This worked great but how do I now make it use a new layout system that has no concept of Left and Top but rather relies on Time or Date? In the old days it would have been difficult to do. Let's look at a way of doing it now:

As we discussed earlier, a control can remember a property even if that property doesn't exist on it. That is great, let's look at a practical example:

If I replace my StackPanel with a DockPanel, I can then set each child control to a specific type of dock.

<Button x:Name="btn1" Content="Button #1" DockPanel.Dock="Top"/>

Now, if the dock panel does its rendering and layout, it can interrogate each item for information on how to display it!!!

This dramatically reduces the amount of predefined properties we need and makes the layout options endless!!!

Have a look at my 2 CodeProject articles for more ideas on how to use Attached Propeties practically.

Posted by rudi | 3 comment(s)
Filed under: ,

Review: Blendables Essentials Mix v.1.0

 

This week I decided to review some of the commercial available WPF controls. The first set of controls I wanted to review was the Blendables Essential Mix available from IdentityMine. The blendables package has 10 controls and cost $395. Here are some of the controls I loved:

Control: DragAndDrop

The first "control" I evaluated was the DragAndDrop attached properties. I have to admit that this had me hooked! This added full drag & drop support to any ItemsControl with only 1 line of code.

How it works

To enable dragging on a ItemsControl just add the following to the controls definition

<ListBox Name="myListBox" blendables:DragAndDrop.Enabled="True" />

Well, that was easy enough! This also works on ListView, TreeView, etc. Next, we need to enable dropping inside a ListBox. New controls are defined here: DragAndDropListBox, DragAndDropListView and DragAndDropTreeView. Just add any 1 of these and you can now drop your items in them. Except for adding the dropping functionality, thy function exactly as their normal WPF equivalents would!

<blendables:DragAndDropListBox Name="myListBox2" />

What I didn't like

Nothing... Works great!!!

Can I get this for free

Pavan's blog has an excellent 4 part article on how to get started... Just know that this is not easy!!!

Part 1

Part 2

Part 3

Part 4

It's also worth mentioning Josh Smith's CodeProject article about drag & drop available here

 

Control: TimelinePanel

This in my opinion is a very cool control. Fundamental to WPF is the concept where content can be organized based on the layout panel that it gets added too. By default WPF ships with Grid, DockPanel, StackPanel, WrapPanel, ect. but it is possible to create your own. TimelinePanel emphasize the chronological nature of your data.

How it works

First you add the TimelinePanel to your visual tree and set the BeginDate and EndDate

<blendables:TimelinePanel BeginDate="01/01/2007" EndDate="12/31/2007">

Next, start adding your content

<Image Width="300" blendables:TimelinePanel.Date="02/15/2007" Source="C:\Picture001.jpg" />

<Image Width="300" blendables:TimelinePanel.Date="10/01/2007" Source="C:\Picture002.jpg" />

And set its date by using attached properties...

What I didn't like

Again, NOTHING!!! Very cool layout panel

Can I get this for free

Read Charles Petzold's book Application = Code + Markup. It has a whole chapter about this... He also creates a new layout panel called a RadialPanel. There are also loads of resources available on the internet!!! Also read up on UI virtualizing...

 

Control: ChromelessWindow

ChromelessWindow is a very cool utility class which easily adds glass effect, dragging and resizing to custom branded windows again using attached properties!!!

How it works

To make a normal window chromeless, just add the following to your window definition

AllowsTransparency="True"

WindowStyle="None"

This is still standard WPF stuff... Things to note here are that you cannot resize or move this window anymore!!! To make it draggable, add the following

blendables:ChromelessWindow.IsWindowDragHandle="True"

To make it resizable, add the following

blendables:ChromelessWindow.ResizeBorderThickness="5 5 5 5"

You can even change the corner radius of the window

blendables:ChromelessWindow.RadiusX="5"

blendables:ChromelessWindow.RadiusY="5" 

This is still all available in Vista or XP. Next, let's add glass effect to our window. This is only available in Vista and Aero them must be enabled

blendables:ChromelessWindow.IsGlassEffectEnabled="True"

Also play around with the GlassBorderThickness, IsGlassColorEnabled, GlassColor and IsGlassTransparencyEnabled to change the appearance of the glass effect!

What I didn't like

I was a little disappointed with this. The ResizeBorderThickness seems a little buggy and sometimes they talk about IsWindowDragHandle and other times they talk about IsWindowDragEnabled. Also If you run the mixer demo it creates the illusion that it is easy to add the minimize, maximize and close buttons to a chromeless window... well, you have to create those yourself!

On the up side, I was very impressed with the adding of the dragging of the window!!!

Can I get it for free

Adam Nathan has a blog entry about how to enable the glass effect available here

[UPDATE] Here is a CodeProject article on how to enable the Glass Effect using attached properties!

To add dragging and resizing to chromeless windows is a little more difficult thou...

[UPDATE] While browsing I found a nice article on Lee's website on how to enable dragging of chromeless windows...

 

What else is available

Carousel3D, Pie and Zoombox controls are also worth looking at. Blendables also includes EvalBinding, SimpleBinding, NumericRangeToObjectConverter and OSChecker!

Where can I get it

http://www.blendables.com/products/products.aspx

Final thoughts

I have to end this review by saying that in general I liked most of the controls in Blendables! I can definitely see myself using some of these controls in the future... would I pay almost $400 for it? The jury is still out on that one! If you want to know more about Blendables, download the evaluation version and run the Blendables Mixer application or download Tangerine... Most of the controls are demonstrated in these applications...

Next on my review list is NetAdvantage for WPF by Infragestics so check back soon...

Posted by rudi | 18 comment(s)

How to create a custom animation in WPF

While working on a project, I needed to create a simple background effect of stars scattering in a specified direction and then fading out. I tried various methods of creating this effect but finally decided to try and create my own custom animation type. I derived from DoubleAnimationBase and made my own double animation that basically create a COS graph.

Let's start to look at the mathematics of how to create this graph. Here is a excel graph of what I wanted to achieve

There are 2 parts to this equation

First calculate the un-scaled current value. This is a value between -1 and 1

unscaledCOS = COS(2 x PI x timeFaction * Frequency)

timeFraction is provided by the animation subsystems. This is a value between 0 and 1. This indicates the current progress of the animation (0 = starting and 1 = finished)

Next, we need to scale the current progress

delta = ((MaxSpan - MinSpan) x timeFraction)/2

scaledCOS = delta - (unscaledCOS x delta) + MinSpan

Next, we need to create a new Animation type called COSDoubleAnimation

My animation had the following properties

MinSpan

This is the minimum difference that the translate transform should move

MaxSpan

This is the maximum difference that the translate transform should move

Frequency

This is the total amount of full "waves" that should be created

All of these properties are defined as dependency properties

To create a custom animation, you should do 3 things.

1) Derive from <type>AnimationBase (The are other methods to but this is the easiest)

I derived from DoubleAnimationBase

public class COSDoubleAnimation : DoubleAnimationBase

2) Override CreateInstanceCore

This function create a new Freezable object

protected override Freezable CreateInstanceCore()
{
    return new COSDoubleAnimation();    
}

3) Override GetCurrentValueCore

This is where all the work happens

I basically just took the mathematic equation created earlier and implemented it. Here is the code:

protected override double GetCurrentValueCore(double defaultOriginValue, double defaultDestinationValue, AnimationClock animationClock)
{
    double minSpan = MinSpan != null ? (double)MinSpan : defaultOriginValue;
    double maxSpan = MaxSpan != null ? (double)MaxSpan : defaultDestinationValue;

    double timeFraction = animationClock.CurrentProgress.Value;
    double delta = ((maxSpan - minSpan) * timeFraction) / 2;
    double unscaledCOS = Math.Cos(2 * timeFraction * (double)Frequency);
    return (delta - (unscalledCOS * delta)) + minSpan;
}

All that is left to do now is animate my stars using XAML

<src:COSDoubleAnimation BeginTime="00:00:00" Duration="00:00:05" MinSpan="0" MaxSpan="100" Frequency="17" Storyboard.TargetName="star4" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)"/>

And this is what the effect looked like

 

Nice!

Posted by rudi | 4 comment(s)
Filed under:

Why is Windows XP Embedded not popular in South Africa?

This is a question I have been asking myself for a while now... Why aren't more people using XPE? Let's start by looking at the pros of XPE:

Disclaimer:

This article is not about XP versus Linux or any other OS... The article only highlights why you should consider using XPE and not XP/Vista...

Why use XPE and not XP professional? Well, XPE is first of all +/- 30% cheaper than XP Pro. This might not seem like a major difference but a typical project roll out of XPe devices are usually high volume. A R100 saving on 2000 units are substantial!!!

XPE is a componentized version of XP Professional. What this means is that I can build an image and remove any component that I might not need. I can literally remove anything I don't use... Why would you want to do this? Well, if I remove all the component I don't use, I can potentially reduce my XPE image size. This reduces the surface of attack and also reduces the minimum requirements of the PC running it. An average XPE image can be anything from +/- 200MB up to 750MB. In today's day and age where storage is cheap, why would you worry about size? Solid state storage is still relatively expensive. A 1GB industrial Compact Flash cost +/- R300 when you could have bought a 40 GB HDD for the same price!!! The added advantage of using solid state storage is that is can handle high vibration (because it has no moving parts). This is a huge advantage if your device is potentially going to be used in a vehicle! Arguably not all devices are designed to be used in a vehicle, so what else can XPE offer me?

XPE by nature is very configurable and can be configured to create the "illusion" of not being a windows operating system. Even the start bar at the bottom can be removed and a custom shell can be created to only load your application. This, first of all secures the device from tampering. It also allows you to make your device appear like a consumer device. Fast boot up, custom boot up screen, etc.

Imagine your DSTV decoder... What would you have thought if it needed to boot up, show a windows boot up screen, etc? XPE allow you to make your device work more like a device as oppose to a PC!

Another huge advantage that some people don't realize is that ANYTHING that runs on XP can potentially run on XPE!!! On Windows CE you are forced to develop using VCe or .NET compact framework. With XPE you can write your application using tools you are familiar with... Delphi, Borland C++ Builder, C#, VC, etc... As long as the resulting application can run on XP, it is possible to make it work on XPE!!!

Still not convinced? Well, XPE also have Embedded Enabling Features (EEF) that is added to make your embedded device function better... I will only highlight 3:

Alterative boot mediums like USB memory sticks and CDs. This can make servicing of devices easier by making a separate image that can be used to diagnose a field device. When you get to the field device, insert the memory stick into the system and restart is. When it boots up again, it runs the "diagnostic" XPE image with all the tools to analyze what is wrong with the system...

The next feature is the Enhance Write Filter (EWF) and the File Based Write Filter (FBWF). This allows you to make your storage medium read only (EWF) or select folders that should be read only (FBWF). Why would you want to do this? Compact Flashes doesn't last forever. It only has a limited amount of write cycles. By making it read only, you can increase the reliability and life span of your storage medium! As an added benefit of EWF, XPE also supports Hibernate-once-resume-many (HORM). HORM does exactly what it says. The first time your run your device, you set it up with the correct applications running, etc and then hibernate your device. All the subsequent startup will then start up quicker (Imagine hibernating your laptop) and will also start up in the same state!

Lastly, the Device Update Agent helps to maintain devices in the field. It is a very basic idea but works well. The DUA checks a know location for scripts. If I new script is found, the DUA executes it... Scripts can update applications, drivers, etc... This reduces technician's trips to field device!!!

This all sounds great, so why is it not doing well? I think the first problem is support in South Africa. If you phone Microsoft SA and ask about XPE, they will not be able to answer your questions. There are no recognized experts like MVPs or even just Microsoft employs who knows about XPE? The second issue is where do I buy XPE? The only 2 places that I know of it being sold (and please correct me if I am wrong) are Centurion Micro Electronics (My employer) and Avnet Kopp?

Hopefully there would be an effort from Microsoft to correct these problems...

To end this looooonnnggg rant... I will be presenting a SADeveloper.net talk soon about XPE. More specifically, I will be giving you a developer's view of how it can be used in your next device. I will show how to create an embedded device end to end. I will first present the developer side of the discussion... writing an application that can run on XPE. This application is going to be a photo kiosk application written in WPF. I will also give pointers about WPF on XPE, performance issues, common KIOSK practices, etc. The second part will be more about why I used XPE and a basic overview of using XPE.

Still to be confirmed but Lynda Allen from Microsoft USA might also join us to give a talk about XPE...

I will post more details as soon as it is confirmed!!!

Posted by rudi | 3 comment(s)
Filed under: ,