Textures can make your application beautiful. Here’s an example from http://subtlepatterns.com, which is full of classy textures:
A nice tile texture
These textures can make great backgrounds, but because the texture is usually smaller than your application (especially tiny textures like ), you need to repeat (tile) the image vertically and horizontally. Images that “match up” on opposite sides are ideal. All the images on http://subtlepatterns.com, http://bgrepeat.com and http://www.repeatxy.com are tileable.
So how do you program your application to repeat this image across a surface? In HTML, you can use the css style “background-repeat: repeat” to tile an image across your webpage. In WPF, you can set up the TileBrush properties on an ImageBrush to tile an image across your application. But in Silverlight, Silverlight for Windows Phone, or Metro style XAML applications, you’re out of luck.
The easiest solution is to use Photoshop (or cheaper equivalent) to create a huge image that you can set as a background. Just use the pattern tool to tile your texture onto an image that’s bigger than your application’s surface will ever be. The question is: can you guarantee a maximum size? With Metro style XAML applications, there is no maximum resolution. The other problem is that these massive image files tend to use up a LOT of memory. In my case, it was so much memory that I was likely to fail Microsoft’s Win8 certification.
I broke a convention
If I was a WPF Purist I would have never extended a Panel class in order to provide a visual control. I’d have built a templated control (Inheriting from Control), and declared the canvas as a template part, and provided a default template that just contained that canvas in my Generic.xaml file. But my whole aim was to keep memory usage low, and in WPF every visual costs you memory, so I decided to pre-optimise. It’s also simpler this was as I only have to show you one file .
A tilebrush in WPF on a 1000×800 surface will happily repeat a 4 pixel image for you, thousands of times (200,000 to be exact), without breaking a sweat. However, with my TileCanvas, we’re creating an Image visual every time we want to repeat the tile, so you don’t want an ImageSource that’s too small. You have to find a happy balance between a huge image (which uses up a lot of memory by itself) and a lot of small images (where you don’t keep paying for the image data, but you do pay for the visual tree explosion). I have found that by repeating your pattern, Photoshop style, onto an image that’s a sized with a nice round number like 128×128 pixels is a good compromise. This applies to the WPF spike as well as the following Metro solution.
When I tried to port my WPF TileCanvas over to use the WinRT version of XAML controls, I ran into two differences that changed the way I had to do things:
There’s no longer a RenderSizeChanged method – after a bit of experimenting, I decided on the LayoutUpdated event (although adding images causes this event to be raised, so I had to track the old size in order to avoid stack overflow)
ImageSources now start with a width and height of 0. It’s not until the ImageOpened event is raised that you can find out the width and height of an image. And you don’t get an ImageOpened event until your image is loaded into the Visual Tree. To get around this chicken-and-egg situation, I add a single image to the canvas, and then once it’s opened and I have the width & height I do a proper layout of the whole screen. I also attach to the ImageFailed event to help you debug, and clean up my event subscriptions once they’ve fired.
Here is my working Metro-style TileCanvas:
One thing that I would add in future would be to not throw away the entire canvas of images every time it was built. It would be better to determine just how many images need to be added and removed. At the moment, this isn’t a big issue because metro apps are always fullscreen so they don’t change size unless you snap/rotate them.
Windows Phone 7.5 (Mango) lets your app create multiple live tiles on the phone’s start screen (with the ShellTile api). This is a very cool way to provide deep links into your application. It’s used brilliantly by the the native apps for contacts (you can pin people and see their individual updates), office (you can pin documents), and music & videos (you can pin albums and playlists).
When you create a new ShellTile, you get to specify one or two image URIs (for the front and back). If you use a relative URI, then the shell will look for the image inside your XAP – just like any other image URI in your app. But that means you only get to use images that you ship with your app – how does the music & video app render the album art for each tile? What if you want to take a screenshot of the current game and use that?
One answer is to use or generate images on the internet and use an http-schemed URI, but that approach can cause the tile to unpin when you turn off your phone (I don’t know if that’s a bug or a feature), and you’ll also be relying on an internet connection.
The best option is to save the image to your application’s isolated storage, because you are free to save whatever file you like there (with full control of the content and format), and the image will always be available (so your tile won’t unpin). If you’ve already sourced your image from the internet, then you can just save it to iso storage, but what if you want to generate an image on the fly? Have a look at the mail app, and how it tells you how many emails you’ve got in big letters. If you’ve got no unread email, it adjusts the position of the email icon too. This image is probably built on the fly by a background process.
But what’s a good way of rendering text and images to an image file?
In my opinion, the best way to render custom, dynamic content in a Silverlight app is to leverage the platform: just render some XAML. If you create a 173 by 173 control, you’ve got full control of how those pixels will look. You can even use databinding. You can use the WriteableBitmap. It’s got a constructor that takes in a UIElement (which will immediately render that element into the bitmap) and a SaveJpeg extension method that will write the bitmap to a file.
In my Bus Alert London WP7 app, I used this technique to render custom tile icons with maps in the background:
Bus Alert Tiles
In the process, I discovered a few very important gotchas:
The UIElement that you render has to be in the application’s visual tree when you call the WriteableBitmap constructor. Otherwise, it may not render at all, may lay out incorrectly, may not have access to the correct StaticResources, or databinding may not occur. You can put it in the visual tree, render it and immediately hide it so that the user never sees it if you like. Unfortunately, this rules out the use of XAML to produce live tiles from background agents.
The image must be stored under the special directory \Shared\ShellContent in your isolated storage folder or it will not be accessible by the operating system.
If you don’t close the image’s filestream before creating the live tile you will see a weird bug where the live tile’s image is only visible when you are moving it around the start screen
I’d always been hoping that C# would introduce something similar to the “typeof” operator that would help you get the name of the current property (or method) without having to use any slow reflection. Before the “//BUILD/” conference, I had given up on C# 5 bringing in anything useful here.
But then I was reading Colin Jack’s summary of the //BUILD/ talk on Future directions for C# and Visual Basic, and was particularly interested by the new Caller Info Attributes feature of C# 5. This feature is not in the CTP of VS11 yet, so I can’t test it, but I expect you’ll be able to write the following RaisePropertyChanged method:
and now when you call this method from a property setter, leaving out the optional parameter:
public string UserName
the compiler will fill out the parameter for you, passing “UserName” to the RaisePropertyChanged method.
What I like about this is that the compiler is creating the magic string for you on every compile – so when you rename your property, the string is automatically kept in sync. This is the best of both worlds, we get the performance benefits of a hardcoded string literal, while keeping everything DRY (and therefore hard to inadvertently break).
Don’t ask me how I got into this situation, but I found this out the hard way.
A quick search will tell you that with Silverlight Local Messaging each message has to be under forty thousand characters, but I haven’t found anything on the internet yet that tells you that you can have a maximum of 255 channels open at a time. So I’m taking responsibility and putting it out there.
Going over the limit will give you a cryptic COM exception, and channels can be “leaked” if one browser process crashes while another is open (for example iexplore.exe and chrome.exe, or just two instances of chrome.exe). Often closing all browsers will clean up the phantom channels, but not always.
Remember that other Silverlight applications might be using some of these channels too, so you should always design your application such that it uses a minimum number of channels.
Power Assert .NET is a .NET port of Groovy’s PowerAssert, which replaces your normal unit test assertions.
Unlike the standard assertions built into nunit, MSTest, and xunit etc; Power Assert gives you a breakdown of all the values within your assertion expression, making it quicker for you to hunt down the cause of the test failure:
One of the new .NET technologies that is really exciting to me these days is the Reactive Extensions to .NET (RX). Sometimes it’s called LINQ to Events, because you can write LINQ queries against future values (events, nicely wrapped up into the IObservable<T> interface), instead of against existing collections (IEnumerable<T>). This technology is especially useful in stateful programming models, such as when you’re building ViewModels for WPF or Silverlight. Once you start programming with RX (although it’s got a steep learning curve!), you start to see lots of places where it would really help make your code simpler. I saw one such place: whenever you need to programatically respond to an INotifyPropertyChanged notification.
INotifyPropertyChanged is an interface that most viewmodels need to implement. It’s used implicitly by the Silverlight and WPF data binding system to register a databinding’s interest in the fact that a property has changed, thus keeping all bindings to the same property up to date. When you implement it, you’re responsible for firing a PropertyChangedEvent event every time a property changes, with the name of the property as a parameter to the event.
Sometimes, you might want to programatically watch changes to a property too. Imagine a screen where users can add rows of data that represent orders. If there needs to be a “grand total” on the screen, then one viewmodel (possibly the root VM for the whole screen) will want to subscribe to the PropertyChanged event of each of the order’s Viewmodels. However, there’s a nicer programming model for listening to updates (events etc) than the INotifyPropertyChanged event…
IObservable is the core of all RX programming (like IEnumerable is to LINQ). If you want to expose a source of data, you need to expose an IObservable. There’s already a utility method to turn an event into an IObservable. But this Observable will publish IEvents, which isn’t quite what I was after. What I wanted was to create an IObservable of the new values of the viewmodel’s property. Just like LINQ, we can use the “Select” method to acheive this.
An Expression is a C#3 construct that allows you to pass expression trees around. This is a very popular way for you to strongly type property names, because you can reflect over an Expression> to get the name of the Property. You can also Compile() the expression to be able to execute it. My method uses both of these: It needs to know which PropertyChangedEvents it should react to (the Where() clause), and it needs to read the new value out (the Select() clause).
Here are the unit tests for this extension method. I had to create a dummy view model class to test, named “PropertyChanger”. Note how you can supply “true” to the startWithCurrent parameter to make sure your subscription will instantly start with the current value of the property, as well as receiving new values whenever a PropertyChangedEvent is fired.
David also gave a great presentation on BDD at the 2010 tech ed in New Orleans, and I highly recommend it for anyone wondering how to get started, or even whether they should get started, with BDD: http://www.msteched.com/2010/NorthAmerica/DPR302
I think this is a good opportunity to talk about some of the new features in StoryQ. My first post on StoryQ came when we’d just committed it to codeplex, and a lot has changed since then:
We’ve moved to Mercurial, which means our users can create public forks
No more ()=> operator. Thanks to FLIT, our fluent interface has evolved to accept plain old delegates, instead of Expression<Action>s.
Tagging. Any Step can be “tagged”, which makes it easy to find in the output report
By default, the HTML report generated by StoryQ is JQuery-enriched, which makes it easy to narrow down stories by class hierarchy or tag. I’m particularly proud of this report – it’s a great way to share test results with everybody, especially when published from a continuous integration server.
A rewritten converter gui, which lets you convert plain text stories into StoryQ code. The new version lets you choose what level of code generation you want (from Story initialisation statement to entire test class), and offers a basic form of intellisense.
The new fluent interface architecture allows us to support multiple (human) languages, and I’m looking forward to creating fluent interfaces for non-english speakers.
I think we’ll be able to create a new way of doing BDD in .NET that takes advantage of C# 4.0′s dynamic features
We still haven’t added xUnit support! Which is lame, because it’s probably going to be really easy…
Please check StoryQ out and let us know if you’ve got any bright ideas for it! And if you’ve never tried BDD, you should definitely look into it. It’s even more fun than TDD!!!