Andrej Tozon's blog

In the Attic

NAVIGATION - SEARCH

NTK2011: Slides and sample code: MVVM

MVVM is a topic that can easily take hours of discussion. Unfortunately, I only had less then one to talk about (at least some of) its goals, parts and possible implementations. Below is my slide deck:

And the code: download

The code is structured in a way that helps you see the changes in the code while progressing through the samples. Just follow the numbers (e.g. MainPage1, MainPage2, and so on). It’s mainly Silverlight code, with the last example being example of an easy transition to Windows Phone.

The sample application is a conference app that lets you see available sessions. I removed the online data endpoint so the online samples won’t work, but you’ll get the feel using the offline data provider. Speaking of data providers, there are three (online/Ntk, using OData endpoint, Offline (loads Xml file from resources), and Json (same as Ntk, just for getting data in Json format – you know, for the phone Winking smile).

Once again, I have to stress out that code is for demo purposes only - while it’s minimized one end, it may be overly complicated on the other. Also, Silverlight Toolkit and JSON.NET libraries that were added through Nuget are not included in the zip.

Ah yes, the slides are in Slovenian language.



NTK 2011 Slides: Silverlight and NUI

I’m publishing the materials from my “Silverlight and NUI” talk from this year NT conference. The talk, where I took the time to dig a bit deeper into Silverlight multi-touch and web camera access capabilities, was part of the whole-day track, themed as “Building applications with NUI”.

[The slides are in Slovenian language]

During my talk, I made some references to the following applications and libraries:

And this is the source code of apps I’d shown: SilverlightNUI.zip:

TouchDemo: primary touch point are shown as blue ellipses, all secondary ones as orange. Pressing the ‘1’ key will bring floating red circles on the canvas – you can move them around if you like. The commented out code changes the behavior of touch events so the primary touch points are not propagated to mouse clicks.

TouchManipulations uses the above-referenced Multi-Touch behaviors that  let you move some pictures around. Keys ‘1’ and ‘2’ will bring up two rectangles that’ll stream your web cam feed, but in different manner: VIdeoBruh vs. ImageBrush with repeated Image captures. [Note: Images included are only placeholders – with the file length of 0 – you’ll have to replace them with proper files in order to run the demo]



Reactive Extensions #3: Windows Phone 7

Following the theme from my previous two posts, this post will be about using Reactive Extensions on Windows Phone 7. I'll use a similar scenario as before – gradually load a few tiles into an ItemsControl. Let’s get started.

Starting a project

Create a new “Windows Phone Application”. Add references to assemblies Microsoft.Phone.Reactive and System.Observable to add support for Rx, then Microsoft.Phone.Controls.Toolkit (found in Silverlight Toolkit for Windows Phone 7) and System.Windows.Interactivity (Expression Blend for Windows Phone 7 SDK, should be already installed if you installed WP7 tools / Expresion Blend 4 SP1).

Layout

Put a ListBox on the main, name it list and possibly change the control to an ItemsControl (we don’t need to select items).

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
    <ItemsControl Name="list" />
</Grid>

Create the ItemTemplate:

<DataTemplate x:Key="TileTemplate">
    <Grid Width="142"
          Height="142"
          Background="{StaticResource PhoneAccentBrush}"
          Margin="5">
        <TextBlock Text="{Binding}"
                   FontSize="{StaticResource PhoneFontSizeExtraExtraLarge}"
                   Foreground="{StaticResource PhoneForegroundBrush}"
                   VerticalAlignment="Bottom"
                   HorizontalAlignment="Left"
                   Margin="20,0,0,10" />
    </Grid>
</DataTemplate>

… use WrapPanel for the ItemsPanel:

<ItemsPanelTemplate x:Key="WrapItemsPanelTemplate">
    <toolkit:WrapPanel />
</ItemsPanelTemplate>

… and update the ItemsControl to use them:

<ItemsControl Name="list" 
              ItemTemplate="{StaticResource TileTemplate}"
              ItemsPanel="{StaticResource WrapItemsPanelTemplate}" />

Reactive Extensions

I copied the code from my previous post:

public partial class MainPage : PhoneApplicationPage
{
    public MainPage()
    {
        InitializeComponent();

        Loaded += OnLoaded;
    }

    private readonly string text = "reactive wp7";

    private void OnLoaded(object sender, RoutedEventArgs e)
    {
        text.ToObservable()
            .OnTimeline(TimeSpan.FromSeconds(.3))
            .ObserveOnDispatcher()
            .Subscribe(AddLetter);
    }

    private void AddLetter(char letter)
    {
        list.Items.Add(letter);
    }

Animating on appearance

Instead of using layout states as in Silverlight version (they are not supported in WP7’s ListBox), I was back on using a behavior to trigger the entrance animation:

public class LoadedBehavior : Behavior<FrameworkElement>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.Loaded += AssociatedObject_Loaded;
    }

    void AssociatedObject_Loaded(object sender, System.Windows.RoutedEventArgs e)
    {
        CreateStoryboard().Begin();
    }

    private Storyboard CreateStoryboard()
    {
        Storyboard sb = new Storyboard();
        DoubleAnimation animation = new DoubleAnimation
        {
            Duration = TimeSpan.FromMilliseconds(1000),
            From = -90,
            To = 0,
            EasingFunction = new CubicEase { EasingMode = EasingMode.EaseOut }
        };
        Storyboard.SetTargetProperty(animation, new PropertyPath("(UIElement.Projection).(PlaneProjection.RotationY)"));

        sb.Children.Add(animation);

        animation = new DoubleAnimation
        {
            Duration = TimeSpan.FromMilliseconds(1000),
            From = 0,
            To = 1,
            EasingFunction =
                new CubicEase() { EasingMode = EasingMode.EaseOut }
        };
        Storyboard.SetTargetProperty(animation, new PropertyPath(UIElement.OpacityProperty));

        sb.Children.Add(animation);
        Storyboard.SetTarget(sb, AssociatedObject);
        return sb;
    }
}

Wrapping up

The last thing to do was adding the behavior to the ItemTemplate and prettify the layout a bit.

That’s it, pretty easy – tiled letters are now gradually filling up the space on the main page, each letter appearing on the screen with a subtle animation. For more details on how that works check out my previous posts on Reactive Extensions.

The demo project can be downloaded from here. In the future I’ll look into using more Reactive Extensions on Windows Phone 7 – stay tuned.

image



My articles on SilverlightShow

A few of my Silverlight articles were published on the SilverlightShow site this past two months. The first one is an introduction to Silverlight/(WPF)/Blend behaviors, where I create a Silverlight Halloween Sound Player without writing a single line of code – the application is composed entirely in Expression Blend, using various behaviors.

Halloween Sound Player

I also used behaviors for another article, to showcase some of the new Silverlight 4 features: WebCam capture support, printing, drag/drop, clipboard, commanding, some databinding enhancements and implicit styling support. The result is a nice doodling application, which can be used to entertain your kids.Camdoodle

The third article was about creating a Europe Weather Map with Silverlight, showing current weather conditions for some of the larger cities in Europe. It was mostly about using the Bing Maps Silverlight Control SDK, but fun anyway.

Europe Weather map

You can expect more articles appearing on SilverlightShow in the next days/months. Leave a comment if you find them useful.



Halloween Live Gallery

With Halloween around the corner, it’s time for some scary photos… In this post I’ll explain how I built my demo application I showed at my Windows 7 Launch talk.

Expression Blend 3 shipped with a few interesting samples, available for immediate use. One of them is called Wall3D (Silverlight 3) and is a great example of one of the new Silverlight 3D features, called perspective transform.

image

This sample (perhaps a starter kit is a better description for it) features a 3D photo gallery, which sort of puts the viewer in the center of an oval “room”, full of photos, with an option to rotate the view to the left or right (flick / mouse click and pan), zoom in or out (mouse wheel), etc.. The kind of what people used to do in Flash; now it’s possible in Silverlight too. The sample serves also as a demonstration of yet another new Blend 3 feature, called Sample data – the photos on the above image were generated through this feature. Let’s explore the sample and see how we can push it further, shall we?

After opening Blend 3, switch to the Samples page and choose Wall3D (Silverlight 3) and the default project will be generated for you. image

You can test the application by hitting F5. You navigate through the gallery by flicking the view left or right and zoom in or out with your middle mouse button.

Examining the code that’s been created in the project will reveal the following:

  • the photos come from the sample data source (XML + photos, which are also included in the project – look into the SampleData folder)
  • “The wall” is driven by the CircularPanel3D control (a custom panel)

Knowing this, we’re ready to create our own 3D gallery. We’ll only need a single thing from this sample project, and that’s the CircularPanel3D.cs file, found in the root of the project. Copy and save that in some other folder for later reference, then start a new Silverlight 3 Application project in Blend.

I used an ItemsControl instead of ListBox to arrange and display the photos. Of course both will accept CircularPanel3D as their ItemsPanel, I just didn’t need item selection in this case. Here’s how it all looked in Blend designer:

Now what’s wrong with this picture? It’s hard to design something when you’ve got no visual feedback to help you with the layout and arrangements. I have already modified the ItemTemplate, but without the actual photos, it’s hard to do proper design work.  And that’s where the sample data comes in. To create a sample data source, open the Data panel and click on the second icon from the right image (Add sample data source). Choose Define New Sample Data, name the data source and click OK. You can shape the sample data source however you like – flat, hierarchical, with entities having simple or complex type properties, etc. For this gallery, I created the following source:

image

Bind this data source to the ItemsControl as its items source – voila!

Cool, much better. Modifying the ItemTemplate has just become a lot easier. Let’s add another element for displaying a bit more details about the photo (like the title and location where it was taken).

Photo view Details view

So we’ve got two views for the ItemTemplate, each view being represented with a separate element – one’s with the photo and the second one with details. We have to provide a way for user to switch between the two; how would we do this? Write code? Call the developer? Not necessarily. If we’re in luck, the appropriate piece of code may have already been written, waiting to be taken it used in Blend for declaratively specifying whatever we wanted to do to those elements and how. That piece of code is called a behavior. There are several places on the web to look for behaviors (as well as more info on what they are and how to produce them), but my first bets would be the Expression Gallery and Expression Blend Samples library on Codeplex; the letter containing some very handy behaviors.

I added a couple of behaviors to add interaction to gallery elements - FlipAction would switch the photo and details part through flip motion, triggered by DoubleClick trigger; and ScaleBehavior would enlarge the photo on mouse over. A couple of clicks for very cool-looking effect.

Let’s take a look at the data source... I decided to use Flickr to retrieve the photos, because it’s API is easy to use and can (amongst other things) return geo-location of the place where photo was taken (when available). This geo-location is then passed to the Bing Maps geocoding web serviceas an input parameter to retrieve the real-world address; these addresses can be seen on the bottom of the flipped photo.

image

Playing with geo-location was fun so I decided to take it a step further. I put together a special ShowMapAction, which is currently triggered by a mouse wheel over the photo (or details). The action simply shows the location on the interactive Bing Map (I used Bing Maps Silverlight Map Control for this).

image

Just a word of caution: Geo-encoded photos are cool, but be careful what you’re publishing on the net. The information may not always be used for good purposes.

The final result can be seen here (live). Right in time for keeping track with what’s going on on Halloween.

Finally I have to say I’m spending a lot more time in Blend since version 3 got out. It’s evolving into a great tool and behaviors are going to take a significant part in designer’s/integrator’s role in the future.

http://tozon.info/gallery/



Silverlight LOB: Validation (#1)

When taking about data validation in applications, I usually describe the validation as the five-stage process or, put differently, five lines of defense against invalid data. In this post, I’ll write about the first line of defense – preventing the user entering the wrong data.

1. Preventing invalid input

This one’s logical, really. A user enters the data through input fields on some kind of input form, so naturally this would be the best place to put our first line of defense.

The first line of defense is about preventing user to enter invalid data into input fields. This doesn’t mean that if done proper and thorough, we wouldn’t need other places to check the data; it’s just the best place to filter out majority of faulty input that can happen during manual data entry. The goal here is to catch as many invalid data as possible, as soon as possible. This wouldn’t result only in better application responsiveness (no unnecessary trips to the server), the immediate feedback of invalid entry will provide a better user experience, possibly even educate the user to learn from her mistakes.

So, what are we talking about here?

A simple TextBox might not be the best solution for entering only numeric data. Seeing the TextBox on the input form, the user might expect she can enter anything she likes into the box, even if the label, put close by the input box, is saying to her: “Enter your age”. A kind of a NumericUpDown control visually gives user a much better idea of what should go into that box, plus she gets an option of manipulating that value; in this case, it’s adjusting the value with the Up and Down keys. In Windows Forms, for example, I liked to use a TextBox with a calculator dropdown for entering decimal data. Masked input boxes also work well, when you want the user to enter the data in a specific format.

If you don’t want to provide any visual clues that only numeric data should be entered in the input field and go for the standard TextBox, it’s very much recommended to handle the input for yourself and only allow numeric keys through. This is usually done by hooking into KeyDown event – either in codebehind class, or even better – with a custom TextBox behavior.

Yet another good example of filtering the data input to the underlying data type, is the DatePicker control. You can usually set the range of valid dates that can be selected and control whether or not date entry is required. With Silverlight DatePicker, it appears that date entry is always optional, even if bound to a non-nullable DateTime data type. Tabbing out of the DatePicker will leave the input box empty, but the bound property will still contain the old value. Hooking into DateValidationError or BindingValidationError event wouldn’t help so I tried to handle this case by manipulating the Selected date in the SelectedDateChanged event. Instead of doing it in the codebehind class, I created the following behavior:

public class RequiredDatePickerBehavior : Behavior<DatePicker>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.SelectedDateChanged += OnSelectedDateChanged;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.SelectedDateChanged -= OnSelectedDateChanged;
    }

    private void OnSelectedDateChanged(object sender, SelectionChangedEventArgs e)
    {
        if (e.AddedItems.Count == 0 && e.RemovedItems.Count > 0)
        {
            AssociatedObject.SelectedDate = (DateTime)e.RemovedItems[0];
        }
    }
}

… which can be used as:

<controls:DatePicker SelectedDate="{Binding BirthDate, Mode=TwoWay}"
                     Grid.Row="1" Grid.Column="1">
    <i:Interaction.Behaviors>
        <local:RequiredDatePickerBehavior />
    </i:Interaction.Behaviors>
</controls:DatePicker>

Attaching this behavior to the DatePicker will revert the date to the last valid value in case of deleting the text from the input box and thus making the DatePicker non-nullable.

Behaviors in general are a great way to extend an existing type (or types) of control and can be used for a variety of things. In this post I’ve shown a way to enhance the Silverlight DatePicker control to prevent entering empty values in cases when date is required. Remember next time you’ll find yourself coding KeyDown or similar control event handler in page’s codebehind class: consider writing a behavior!

To be continued…

Shout it

Creating Silverlight Behaviors (with Blend 3 Interactivity dll)

Behaviors are not new in WPF / Silverlight world; it’s a common way of extending visual element’s behavior through the power of attached properties and everybody probably used one of these at least once in their projects. Now, there’s new Behaviors in town…

I first learned about the behaviors in this excellent, short but sweet MIX09 presentation by Pete Blois. In short: the new “breed” of behaviors will be supported in Blend 3, allowing designers to easily extend visual elements by drag’n’dropping a variety of behaviors onto them. If you’re not familiar with what behaviors are – imagine you have a Drag behavior... By setting it to any element in your window (in Blend / Xaml, no .NET code!), that element instantly gets draggable around that window. Yeah, that’s a powerful concept. And it doesn’t stop there. Watch the video, it’s worth the time…  And for detailed info, Christian is running a series on behaviors and other interactivity mechanism in his blog.

What I don’t get is why they are called Blend (3) behaviors, because they are not limited to Blend in any way. They would be as easily called Silverlight/WPF behaviors, or simply – Behaviors. Yes, that means you can use (and create) them even if you don’t have Blend 3 installed. Even Silverlight 3 is not required, it works with version 2 perfectly. You only need a special dll, which gets installed with Blend 3 – Microsoft.Expression.Interactivity.dll. I currently have no idea what the deployment story with this assembly is at the time of the writing (with Blend being in Beta and all), but you’ll find it in the c:\Program Files\Microsoft Expression\Blend 3 Preview\Libraries\[Silverlight] | [WPF]\ folder. This assembly (it comes in Silverlight and WPF flavor) provides the base interactivity classes and is required if you’re going to use behaviors in your application.

It should be quite obvious as to where behaviors fit in the designer / developer workflow: designers will be able to decorate visual elements with various behaviors and see them in action, while developer’s job will be to come up with new, not-yet-existing behaviors that designer had in mind when designing the UX.

There are a few examples of behaviors up and ready on Expression Gallery, but let’s take a look how we can develop our own behaviors using Visual Studio 2008.

The first behavior we’ll look into will be called the TransparencyBehavior. What it will do is make every element semi-transparent when the mouse is not directly over it. I’ll use one of my previous samples (a semaphore) as a building ground for this one. The lights on the semaphore will be semitransparent until mouse enters the light’s space for it to become fully visible. Let’s begin

First, you’ll need the Expression interactivity dll (see above). Once you find it, add it as a reference to your project. Then, create a class, deriving from Behavior<T>. The generic type T is the type of element you want to extend with this behavior. I’m using the Ellipse type for the purpose of this example to show a more concrete implementation. I could also use <FrameworkElement> because this type of behavior is so common it could be attached to element.

Update: updated the previous paragraph to make sense and align with the sample code.

public class TransparencyBehavior : Behavior<Ellipse> {}

We’ll need a couple of properties to control the behavior’s parameter: The InactiveTransparency property will hold an opacity value for element’s inactive state (when the mouse is not over) and the Duration will hold the time for the element to transition from active to inactive state (and vice versa).

To hook into the element we’re extending, we have to override the OnAttached method. It will be called when the element is being initialized so we have the chance to attach additional event handlers to element’s events. The extended element can be reached through the AssociatedObject property. In this method, I’m hooking up into MouseEnter and MouseLeave events to detect when mouse is over, initialize and construct a storyboard that will be triggered for state transition:

protected override void OnAttached()
{
    base.OnAttached();

    storyboard = new Storyboard();
    animation = new DoubleAnimation();
    animation.Duration = Duration;
    Storyboard.SetTarget(animation, AssociatedObject);
    Storyboard.SetTargetProperty(animation, new PropertyPath(Border.OpacityProperty));
    storyboard.Children.Add(animation);

    AssociatedObject.Opacity = InactiveTransparency;
    AssociatedObject.MouseEnter += OnMouseEnter;
    AssociatedObject.MouseLeave += OnMouseLeave;
}
Similarly, there's the OnDetaching method that we can use to clean up (remove event handlers etc.) The rest of the class are just the handlers:
 
void OnMouseLeave(object sender, MouseEventArgs e)
{
    animation.To = InactiveTransparency;
    storyboard.Begin();
}

void OnMouseEnter(object sender, MouseEventArgs e)
{
    animation.To = 1;
    storyboard.Begin();
}
 
To finish, here’s a piece of modified (from the previous semaphore example) piece of Xaml using the behavior:
 
<Ellipse Fill="{Binding Brush}" Width="50" Height="50" Stroke="Black">
    <i:Interaction.Behaviors>
        <local:TransparencyBehavior Duration="00:00:00.2" InactiveTransparency="0.5" />
    </i:Interaction.Behaviors>
</Ellipse>
That’s all for this simple behavior. In future posts, I’ll come up with new behaviors and put them in the context of some other samples I’ve used in the previous posts.
[Hint: in the below sample, hover over green lights]

The way to create new behaviors is very similar to using “direct” approach with attached properties. The Behavior base class provides a very convenient infrastructure to build on, and porting the “old way” attached behaviors to this new model shouldn’t be that difficult. Behaviors are not limited to use in Blend 3 and work with Silverlight 2 too. With that, it would be great to see Microsoft releasing the interactivity dll as a standalone release or a part of some other SDK, not tying it to either Blend 3 or any particular Silverlight version.

The source code for this sample is available. Please note that the project is a Silverlight 3 project and doesn’t include the Expression Interactivity dll.

Update: the above code was updated to match Silverlight 3 / Blend 3 RTM bits. Thanks To Michael Washington for taking the time to update the behavior.

Shout it