silverlight

Silverlight unit testing with NUnit: yes you can (without hacks)!

It may be obvious for most of you, but it took a while to my caveman brain to realize this, so I figured I could post it for other cavemen. You (we) have got an excuse though: the short release cycle of Silverlight means that most stackoverflow questions and blog posts on the subject are out-of-date and refer to older versions of Silverlight (<=3) when what I describe was not possible.

Up to Silverlight 3 you had to use a Silverlight-specific unit testing tool, like the Silverlight Toolkit framework. These tools are quite awesome and have been fundamental, but it’s nice to have the full power of NUnit (or xUnit & co.) at disposal. In addition to the community and tooling support, it’s practical to use the same tool you already use for other .NET projects.

The game changer is called binary assembly compatibility, brought by Silverlight 4. In a few words this means that you can add a reference to a Silverlight assembly from a “full” .NET project (provided that you don’t use any Silverlight-only class).

If your application is correctly layered (for ex. with MVVM) in most cases it’s trivial to keep views and viewModels/models in separate assemblies. ViewModels and models usually don’t reference any Silverlight-only class (otherwise you may have a code smell!) and are 100% compatible with .NET, so testing them with NUnit is as easy as

  • create a .NET class library in your solution
  • add a reference to NUnit (NuGet it!)
  • add a reference to your model and/or viewModel assemblies
  • write your unit tests
  • run them with NUnit

no tweaking or hacking required and works fine with F# assemblies as well.

It is typical for views to use Silverlight-only classes, but this is generally not a problem because it doesn’t make much sense to unit-test them anyways as they are mostly XAML with very little amounts of code-behind.

Free tip: if you want to test internal classes and methods you can add the InternalsVisibleTo attribute to the target assembly.

Happy testing!

bear

Dynamic member binding in Silverlight 4

UPDATE: Xavier Decoster already wrote a nice article on this topic some time ago. Please check it out! (Note to self: improve google skills)

First, let me say that I’ll take the long route, so if you are already familiar with dynamic typing in C# you can probably jump straight to the last section. Otherwise read on, you may learn something cool that is not used every day but can save you in some situations.

In the [not so] old days of Silverlight 3 if you wanted to dynamically create a class you had to emit intermediate language instructions, etc. Definitely not so easy. Silverlight 4 (with C# 4.0) introduced support for dynamics and simplified this a lot.

Straight from the DynamicObject documentation, this simple implementation of a dynamic dictionary uses an internal dictionary to store string/object pairs where the key is the member name and value is its associated value.

public class DynamicDictionary : DynamicObject
{
    Dictionary<string, object> dictionary =
        new Dictionary<string, object>();

    public override bool TryGetMember(
        GetMemberBinder binder, out object result)
    {
        return dictionary.TryGetValue(binder.Name, out result);
    }

    public override bool TrySetMember(
        SetMemberBinder binder, object value)
    {
        dictionary[binder.Name] = value;
        return true;
    }
}

In a DynamicObject you have two methods (TryGetMember and TrySetMember) that are invoked every time someone tries to access the objects’ members. In this particular implementation, when this code is executed

dynamic myDynamicObject = new DynamicDictionary();
myDynamicObject.FirstName = "John";
myDynamicObject.Age = 18;

two pairs “FirstName”/”John” and “Age”/18 are stored in the internal dictionary. On the other hand when you do

string test = myDynamicObject.FirstName;

instead of calling the getter of FirstName (like any statically typed object would do), TryGetMember is invoked and the value corresponding to key “FirstName” is looked up from the internal dictionary.

The dynamic keyword tells the compiler that the member will be looked up at runtime, so you can set/get any member you want and the compiler won’t complain: he knows the members will be resolved while the program is running.

The binding problem

Now there is only a small problem with this approach (and it’s the whole point of this post): if you create a binding that targets a dynamic member you’ll get an error. It looks like the Silverlight binding engine “cannot discover” dynamic properties.

For example this does not work:

public dynamic MyDynamicDictionary {  get;     set; }

// ...

MyDynamicDictionary = new DynamicDictionary();
MyDynamicDictionary.Label = "Hello, I'm dynamic!";
 <Button Content="{Binding MyDynamicDictionary.Label}"/> 

brokenBinding

If you look at the output:

System.Windows.Data Error: BindingExpression path error: 'Label' property not found on 'SilverlightApplication22.DynamicDictionary'

Indexed binding to the rescue

Telerik’s Vladimir Enchev explains on his blog how this approach can be used to implement a dataTable-like structure that can back for ex. a datagrid. The clever bit is that he added to the DynamicDictionary the [] indexer:

public object this[string columnName]
{
    get
    {
        if (dictionary.ContainsKey(columnName))
            return dictionary[columnName];
        return null;
    }
    set
    {
        if (!dictionary.ContainsKey(columnName))
        {
            dictionary.Add(columnName, value);
            RaisePropertyChanged(columnName);
        }
        else
        {
            dictionary[columnName] = value;
            RaisePropertyChanged(columnName);
        }
    }
}

Now we have two alternatives to access the dynamically-created members:

// like before:
dynamic myDynamicObject2 = new DynamicDictionary();
myDynamicObject2.FirstName = "John";
myDynamicObject2.LastName = "Smith";

// using []:
var myDynamicObject3 = new DynamicDictionary();
myDynamicObject["FirstName"] = "John";
myDynamicObject["LastName"] = "Smith";

The two approaches have exactly the same effect (notice that in the second version the variable is declared with var instead of dynamic).

Using square brackets to access members has the advantage that you can actually create members using strings: let’s say you have a string/object dictionary, it’s easy to loop the dictionary entries and “create” a member for every key while setting the value as the member value. After this you’ll have an object that mirrors the dictionary:

var source = new Dictionary<string, object>();
source.Add("FirstName", "John");
source.Add("LastName", "Smith");
source.Add("Age", 18);

var target = new DynamicDictionary();
foreach (var entry in source)
    target[entry.Key] = entry.Value;

now target is the same as you would have after doing

new something() { FirstName = "John", LastName = "Smith", Age = 18 };

except that it “adapts” to any key/value you have in the dictionary. Cool eh?!

It turns out that the indexer has another side benefit (that solves the binding problem). In fact Silverlight 4 also introduced indexed bindings: you can create bindings that target indexed structures (like a list or a dictionary) simply using square brackets. The nice thing is that our dynamic class happens to have an indexer.

Let’s revisit our code: if we declare the property as DynamicDictyionary instead of dynamic (we now must set the properties using the indexer because the compiler only allows “non-existing” properties on object of dynamic type):

public DynamicDictionary MyDynamicDictionary { get; set; }

//...

MyDynamicDictionary = new DynamicDictionary();
MyDynamicDictionary["Label"] = "Hello, I'm dynamic!";

and change the XAML to look like this (notice the square brackets)

<Button Content="{Binding MyDynamicDictionary2[Label]}"/>

the dynamic binding does work fine:

okBinding

Happy dynamic binding!

Download the code

Windows Phone 7: how to reset the idle detection countdown

Windows Phone 7 like every other phone OS turns off the screen after a period of inactivity. This is not a problem most of the time because any user activity (namely finger interactions on the screen) resets the countdown, so if you are using an application the screen saver will not get in the way. However there are some particular cases where it is useful to disable the idle detection, for example in games or apps that require long reading (or watching). In that case you can completely disable idle detection:

PhoneApplicationService.Current.UserIdleDetectionMode =
    IdleDetectionMode.Disabled;

Keep in mind that this disables the “screen saver” at all, so be careful because you could drain the poor user’s battery if you do it without valid reason.

There is another more interesting case, though: suppose your app uses the accelerometer as its main user input. In this case there won’t be any user activity to trigger a countdown reset, but disabling it at all also doesn’t look like the best idea (what if the user puts the phone on the table to go grab a beer?).

The best in this case would be to reset the count-down when a movement is detected, i.e. treating accelerometer events like screen user input. How to do this?

The answer is extremely simple: you can just disable the IdleDetection and re-enable it again. This will reset the count-down. One little caveat: you cannot re-enable it immediately after having disabled it, the OS is smart enough not to be fooled and will ignore your two commands. You’ll have to wait a short while before re-enabling idle detection.

Here is an example: when I get a new reading from the accelerometer (I’m using the AccelerometerHelper) I check if there has been a large enough movement and in that case I disable the idle detection. Otherwise I enable it –this effectively resets the countdown every time the movement goes above a given threshold. Keep in mind that the accelerometer fires 50 times per second, that’s why I used a bool field to avoid unnecessary calls to the system setting. I’m not sure this prevents an actual performance loss, but it would be worth it to experiment and measure a little if you are using this technique in your apps.

double _currentValue;
bool _screenSaverEnabled = true;

private void OnAccelerometerHelperReadingChanged(object sender, AccelerometerHelperReadingEventArgs e)
{
    Dispatcher.BeginInvoke(() =>
        {
            // you'll have something more useful in your app
            computedValue = e.OptimallyFilteredAcceleration.X;

            var delta = Math.Abs(computedValue - _currentValue);
            if (_screenSaverEnabled)
            {
                if (delta > SOME_ARBITRARY_THRESOLD)
                {
                    _screenSaverEnabled = false;
                    PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled;
                    Debug.WriteLine("Screen saver disabled");
                }
            }
            else
            {
                _screenSaverEnabled = true;
                PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Enabled;
                Debug.WriteLine("Screen saver enabled");
            }
            _currentValue = computedValue;
        }
    );
}

Happy coding!

An error occurred while accessing IsolatedStorage.

While developing a Silverlight Windows Phone 7 app I ran into this problem: when the application closes, an internal  IsolatedStorageException is raised:

An error occurred while accessing IsolatedStorage.
   at System.IO.IsolatedStorage.IsolatedStorageSecurityState.EnsureState()
   at System.IO.IsolatedStorage.IsolatedStorageFile.get_AvailableFreeSpace()
   at System.IO.IsolatedStorage.IsolatedStorageSettings.Save()
   at System.IO.IsolatedStorage.IsolatedStorageSettings.TrySave()
   at System.IO.IsolatedStorage.IsolatedStorageSettings.SaveAllSettings()
   at MS.Internal.FrameworkCallbacks.ShutdownAllPeers()

IsolatedStorageSettings seemed to be the cause of the problem. Very weird because I wasn’t even using it! Just adding this line in my App class would cause the problem:

private System.IO.IsolatedStorage.IsolatedStorageSettings appSettings = System.IO.IsolatedStorage.IsolatedStorageSettings.ApplicationSettings;

Now I created a new, empty, project (Windows Phone Application) and inserted that line. Weird: no problems.
I thought there was something wrong in my solution, so I made a backup copy and started removing stuff. At some point my solution was identical to the default one (except for the IsolatedStorageSettings line and the project’s GUID). Not “almost identical”, but completely, literally identical, i.e. WinMerge found no difference except the two mentioned. And of course the default solution worked while mine gave the IsolatedStorageException on shutdown.

I honestly haven’t understood the cause of the problem, but at least I’ve found a solution: change the project GUID:

  • close Visual Studio
  • open your solution’s .sln file with notepad
  • replace a couple of numbers in the Project(“{<your GUID here>}”)
  • open the .csproj with notepad
  • apply the same change to the GUID (in the first line after the comment and in all the Build Configurations)
  • Re-open your solution with Visual Studio and the problem is gone.

I suspect the problem has something to do with the emulator but I haven’t had a chance to try a real device yet. I hope I saved you an evening of head scratching.

Windows Phone 7 Marketplace subscription for Swiss individuals

Lately I’ve been busy coding stuff for Windows Phone 7 –really fun! If you are a Swiss individual (i.e. you are not developing your apps for a company) then joining the Marketplace is not very straightforward. If you reside in another non-U.S. country you may as well read this post, I suppose you will only have to make minor changes to the procedure.

Sascha Corti of Microsoft Switzerland has provided a great walkthrough, but I whish to add a couple of things, in particular re. obtaining your notarized passport copy.

Sign up

First, you can sign-up to the App Hub on create.msdn.com. You need a credit card to pay the CHF 129 annual fee. Be careful: the publisher name is final and cannot be changed later. So think about it for a minute and if you are not sure wait until you’ve decided what to display as your apps’ publisher.

Payee Details

When you are signed-up and have clicked on all the confirmation links you receive, you have to log into your account and fill in your bank account data under my account/payee details. If you only have a Post account, no problem, use the Post’s IBAN calculator –they also provide the BIC and correct address.

At this point you are ready to submit your applications to the marketplace, but you may want to continue reading. In fact as you probably already know, you will receive 70% of your app’s total sales, the other 30% being kept by Microsoft. The problem is that as a non-U.S. resident, another 30% will be removed from your part –which is a rather big hit IMO! Keep in mind that you will have to pay Swiss taxes on the income, so in the end not much will be left in your hands.

That’s why you have to provide some documentation proving that you are indeed paying taxes on your country –so that the U.S. won’t charge you that infamous additional 30%. In practice, it means asking an ITIN number to the U.S. International Revenue Service and giving it to Microsoft.

Notarized Copy

To ask an ITIN number you need a certified true copy of your passport. The IRS is rather strict on this aspect and won’t accept notarized copies from entities not in their list. This excludes the Swiss Post and probably anything else except the U.S. Embassy.

So -unless you live in Bern or Zurich and can take an appointment- you will have to send the following:

  • your passport
  • a copy of your passport
  • the filled-in W7 form (more on that later)
  • the Microsoft printed letter (more on that later)
  • a CHF 1.00 stamped envelope with your address

to this address:

U.S. Embassy
Consular Section
P.O. Box
3001 Bern

and at the same time, pay CHF 50.- (plus the 18.- postal fee) to

American Consular Services
Sulgeneckstrasse 19
3007 Bern

Yiikes! This will probably be the most expensive photocopy of your life (also considering that you made the copy itself :-) ), but they don’t have a post/bank account so you cannot avoid the 18.- fee.

W7 Form

In some days you will receive your notarized passport copy (and hopefully your passport) back. You are now ready to forward the W7 form. If you sent it to the embassy, they will probably have checked it for obvious mistakes, but I have not yet received mine back so I cannot tell at this time.

Anyways the W7 form can be downloaded here. Fill it in as explained in Sascha Corti’s presentation. In particular make sure that you check point a. and h., and enter “Exception 1 (d) – Royalty Income”  at point h., plus “12” as treaty article number.

Now log into your Marketplace account, go to the payee details page, scroll down until you find “Click here to download the Microsoft letter”, download the letter, print it and hand-write the date and your full name. Make sure the letter includes Todd Biggs signature at the end. A previous version did not include the signature and applications were rejected because of it.

Now send W7 and the letter to

International Revenue Service
ITIN Operations
P.O. Box 149342
Austin, TX 78714-9342
United States of America

After n weeks they will hopefully assign you an ITIN number.

W-8BEN form

With your ITIN in hand, you can finally fill in the W-8BEN form, print it, sign it and send it to

Microsoft
’Windows Marketplace for Mobile’
One Microsoft Way
Redmond WA 98052
United States of America

Once they receive and process it you should be free of the 30% tax and receive your full 70% royalties. As far as I understand it this is not retro-active, i.e. the taxes you previously paid won’t be reimbursed.

That’s all

This should be all (I never said it was simple ;-) ). It takes some effort, time and money (about CHF 80.- one-time plus the annual 129.- fee), but if you are doing some interesting apps it may be worth it as you will hopefully earn it back soon.

 

UPDATE:
Getting your ITIN number from the IRS can take a long time. It took me more than 3 months since I sent the W7 form. Send it with signed mail for piece of mind, and be patient, they will eventually answer.

Best of Swiss Silverlight 2010

During this year’s Shape 2010 conference in Zurich-Oerlikon, Microsoft Switzerland announced the winners of the Best of Swiss Silverlight 2010 Award in collaboration with the Best of Swiss Web Association, simsa and Netzwoche.

best_of_sw_silver_2010

Incredibly my application Trails of Switzerland won the Bronze award. I was completely taken by surprise (not to mention super excited) because I didn’t really expect anything when I started the project. In fact it was just a “weekend project” to try a couple of things. When I saw the award application form I thought it could be worth a try so I polished a bit the front-end and added a couple of cool gadgets.

I was familiar with the competition’s application procedure also because I already did it a few times before for my company (that won this year’s .NET Award by the way).

boss_bronze_2010

My application leverages Silverlight’s DeepZoom component to show a full topographic map of Switzerland. The base image is a huge 19 Gigapixels (~3 Gigabytes) JPEG, but movement and zooming is wonderfully smooth.

The tricky part was mapping the GPS data to the map and then keeping content synchronized with the DeepZoom zooming and panning.

screenshot-1

Currently Trails of Switzerland is in closed-beta at http://maps.frenk.com and will probably never go live (except if someone wants to buy it from me) for the simple reason that copyrights on the maps are incredibly expensive and I cannot afford to buy them “just for fun”.
To be honest I must say that the Swisstopo maps are of incredible precision and quality, but still are way too expensive for a no-profit application.

The good part is that Trails of Switzerland could probably be ported to Windows Phone 7 (with a major restyling of course) as DeepZoom seems to work very smoothly there too.

I’d like to congratulate the other contest winners (Coresystems AG/Misapor, Extrafilm AG, VASP Datatecture AG/ETHZ, Portia AG/Immostreet AG): your applications were really mind-blowing!

Shape

The conference was very interesting as well. In particular Bob Muglia should have taken notes from Ronnie’s talk on HTML5/Silverlight. If you have watched the PDC2010 keynote (and the twitter/blog-storm that followed) you know what I’m talking about.

As always Laurent’s Bugnion’s talks were interesting, but also many others were worth the trip (in particular from a Windows Phone 7 and design/UX standpoint).

Moral: you never can tell

Moral of the story is you never know where a weekend project is going to bring you. It seems that someone else also agrees on this. This is one of the things I love in this field.

Thanks

Thanks to Microsoft Switzerland and most of all thanks to my wife for the continuous support and for understanding when I forget stuff/don’t listen because I’m thinking about code (i.e. most of the time) :-)

Silverlight: web service calls fail when OOB

Situation: your Silverlight 3 application is calling a web service and while it works fine in the browser, it miserably fails in out of the browser mode (OOB).
Don’t panic. It seems that you cannot call a webservice (in App.xaml.cs) before having assigned the application’s root visual. As mentioned, this is not a problem when the application runs inside the browser.

So, for example, this will fail (timeout):

private void Application_Startup(object sender, StartupEventArgs e)
{
    myService.MyMethodCompleted((s, e) => this.RootVisual = new MyPage());
    myService.MyMethodAsync();
}

while this will work fine:

private void Application_Startup(object sender, StartupEventArgs e)
{
    this.RootVisual = new MyPage();
    myService.MyMethodAsync();
}

On a side note, remember that RootVisual can only be set once. I haven’t checked what happens with Silverlight 4, but if you are seeing weird behaviours it may be worth it to check this before setting everything on fire.

I hope I saved you long hours sniffing http traffic, checking for crossdomain issues, etc… :-)

Happy coding!

Silverlight/WPF RGB color in c#

Sometimes you have a color in XAML and want to use it in c#. In other words you want to translate something like:

<Border Background=“#AA0FCC1B”>;

to:

Border.Background = …something…

So you start looking for an IValueConverter that create a color from a RGB string, or translate the hex values to decimal, etc… STOP it!
All you need is:

Border.Background = new SolidColorBrush(
                            Color.FromArgb(0xaa, 0x0f, 0xcc, 0x1b));

doh

Ok, it may sound stupid, but you never can tell…

Silverlight 4 is out…

…just a word of caution for developers: if you are still developing with Silverlight 3 and VS2008 don’t install the Silverlight 4 runtime. If you do, you won’t be able to build your SL3 application anymore and you’ll spend the next hour

a) looking for a way to make your app build again

b) looking for the SL3 runtime (that you won’t find anywhere –and won’t correct the situation anyway).

This problem should not arise if you are already on VS2010 because it allows you to choose your target between SL3 and SL4, but if you are stuck with VS2008 you are out of luck.
It seems that the folks at MS think that everybody can just go ahead and migrate all their solutions to VS2010 and SL4 the next day things are released.

Epic fail! Rant over.

P.S. the correct way to make things work again is:

– uninstall the Silverlight 4 runtime (listed as “Silverlight” in the Programs & Features panel)
– restart your machine (no, you cannot skip this step!!!)
– download the Silverlight3 Developer Runtime and install it (hurry up because as soon as they’ll notice they will remove it from the download server!)

And no, you won’t be able to view SL4 websites –but at least your app will build.

UPDATE: forget the rubbish above. If you install the Silverlight 4 developer runtime you will be able to run SL4 apps and build SL3 apps (of course if you had the SL3 SDK). Just don’t install the “normal” SL4 runtime.

WPF is dead. Long live WPF!

Some months ago I read in a blog post that Silverlight ate WPF from the inside. I had a good laugh and thought it was the most foolish thing I’ve read in a while. I even posted a comment that (thankfully) never got published. Having worked extensively with both WPF and Silverlight I thought the two things were not even remotely comparable. While WPF provided great power, Silverlight was full of limitations and getting any real work done was frustrating and painful.

Turns out I was wrong. Completely wrong! This week I attended TechDays (the small version of MIX that Microsoft does in European countries) and while nobody says it explicitly, the strategy at Redmond seems pretty clear. Silverlight is progressing at an impressive pace and WPF is not getting many exciting improvements. The gap is still there (still large to say the truth), but seeing SL reach and eat WPF is not that difficult. I think MS is pushing in that direction with all their forces.

Out of the browser was almost a gimmick in SL3, but with SL4 they revealed their cards: they added so many features (even COM support when running in Windows) that it’s now doable to build a desktop application entirely based on SL. You can even deploy it directly on the desktop without any browser interaction.

I’m pretty sure it will only take a few of years for Silverlight to be the Windows UI library, with the big bonus of true multiplatform, small runtime and web deployment with a single codebase. WPF won’t loose anything as it will just be part of Silverlight.

This is the future I think. Unless I’m completely wrong again.