Andrej Tozon's blog

In the Attic

NAVIGATION - SEARCH

Detecting duplicate instances of a running Silverlight application

This is a short tip for constraining your Silverlight applications to a single instance, something that’s quite popular in the desktop applications world. What you want to do is allow only the first instance of your application while rejecting all subsequent instances.

Silverlight 3 introduced a way for applications to communicate between each other, either on the same page or instantiated on a different browser instances (works even with Installed/OOB apps). The communication is performed by sender and receiver classes, which exchange messages through named channels. Each receiver must register a unique name for the channel or an exception will be thrown.

And that’s the trick. Listening on a specific named channel will act like a mutex. By catching the ListenFailed exception you get an option to display appropriate message or launch a different version of the application. All the work is done in App.Xaml.cs file:

private void Application_Startup(object sender, StartupEventArgs e)
{
    try
    {
        receiver = new LocalMessageReceiver("singleinstance");
        receiver.Listen();
        this.RootVisual = new MainPage();
    }
    catch (ListenFailedException)
    {
        this.RootVisual = new DuplicateInstancePage();
    }
}

The test project is available through here.



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/



Windows 7 Launch talk: Building cool applications with MS Expression tools

Windows 7 launch day was fun. I gave a talk on Expression tools (and related) – here’s the PowerPoint slide deck for those who asked for it:

I used Expression Blend 3 to build a photo viewer application, which I’ll blog about later; key points here were designer-developer workflow + using sample data and behaviors.

I blogged about the Microsoft ICE last year and I used that exact sample I’ve used in that blog post, but with one difference: did you know that by installing ICE on your desktop will, you can stitch panoramic (or large composite) photos right from your Windows Live Photo Gallery? It’s as easy as selecting the photos and click on the Extras menu item:

Create Image Composite...

Yet another option for stitching a bunch of photos together will give you the Deep Zoom Composer(free and not listed as an Expression tool, but sure looks and feels like it), which has similar features and much more compositing power (different zoom levels, layers, etc.)

And for closing I briefly showcased Expression Encoder 3 and IIS Smooth Streaming.

Yup, fun.



Slides and demo from Bleeding Edge’2009

On this year’s Bleeding Edge conference I had a talk on debugging with my fellow SQL Server MVP. While he covered some common pitfalls, awaiting developers on the SQL Server side, I focused on the Silverlight side of development and debugging:

  • possible issues with application deployment
  • options and strategies for returning WCF faults with Silverlight 3
  • using windbg with Silverlight application to track its execution
  • finding data binding failures and memory leaks

This was our sample application: Bleeding Edge Shoppe[opens in new window]

Bleeding Edge Shoppe

[The full source code will be available shortly.]

And the slide deck:



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