Monday, 10 March 2008

Converting SilverlightAudioPlayer to Silverlight 2.0 Beta 1

I've now got round to revisiting my Silverlight Audio Player control and updating it for Silverlight 2.0 beta 1. The addition of a controls library into Silverlight 2.0 meant that I could ditch a whole load of code straight away.

MediaElement

I also noticed some nice improvements to MediaElement. CurrentState is now an enumeration and the Attributes property has been changed to a dictionary. Unfortunately though, Attributes is still not populated with anything when you load an MP3 file. I had been hoping for it to read the ID3 tags.

Custom Templates

Silverlight Audio Player

To implement the position slider, I made a user control consisting of a green rectangle with a slider on top. The rectangle is used to indicate download progress, and so can be adjusted in width. The slider sets the position

Having done this, I wanted to change the appearance of the slider so I got hold of the default templates for the slider control from MSDN and pasted them into my UserControl.Resources. Unfortunately it didn't compile because of an issue with the way that Colors were added as static resources in the template for the Slider's thumb control. Fortunately, I was able to delete the majority of the code as my Thumb control was simply going to be a circle that changed colour with mouse over. The slider background I changed to be a taller transparent rectangle, so that the download progress rectangle could show through from behind and look like it was filling up the progress bar.

Silverlight Audio Player

So it is remarkably easy to supply your own style to a standard control (so long as you have an example to copy!). The next step will be to see whether I can allow a user to completely override the style for my entire SimplePlayer user control, but I am not sure how easy that will be, as Karen Corby's MIX presentation on Silverlight controls (highly recommended) seemed to suggest that styles could only be applied once and that styleable controls needed to be created in a different way (storing their default styles in a generic.xaml file and using attributes to indicate what "parts" they needed).

What's in the XAP?

One of my goals with Silverlight Audio Player is to make it as simple for people to deploy onto their web-sites as possible. The XAP file will go a long way to making this possible. You can see exactly what is in your XAP file by simply renaming it to .zip and loading it into any zip file extractor. This was useful for me, as I had been a little unsure as to whether any of the files in the ClientBin directory were needed in addition to the XAP file.

RectAnimation

Sadly, the RectAnimation I wanted to be able to animate the clip rectangle of my canvas didn't make it into Silverlight 2.0 beta 1. Maybe next time.

Saturday, 8 March 2008

More thoughts on Silverlight 2.0 beta 1

I'm continuing to update my SilverNibbles application in an attempt to try out some of the new features in the latest Silverlight beta.

In addition to the things I mentioned in my previous post, here's some things I liked, and some things I learned:

Being able to reference UserControls directly in XAML is brilliant. It has greatly simplified a lot of the code in SilverNibbles.

Intellisense for XAML is great!

The cursor keys finally work properly. Previously they didn't give any key-down events, only key-up.

There is a new DispatcherTimer object that can be used for game loops in preference to having to use an animation of an invisible object.

Buttons can respond to keyboard events even if their container is invisible. You need to set the IsEnabled property to false if you don't want them to be triggered by the space bar or enter key.

Layout panels are nice, but can actually cause a lot of headaches wondering why your user-control is sizing itself in unusual ways. Sometimes Canvas is still the most straightforward thing to use.

The app.xaml file is nice in that it lets you set Style and Template resources. What I would really like to do is something like this:

<Application.Resources> 
<SolidColorBrush x:Name="BackgroundBrush" Color="White" /> 
...

and then in a user control:

<Rectangle Fill={StaticResource BackgroundBrush}/>

I haven't done enough WPF to know whether this would be allowed in WPF, but it would be a very useful feature if you could.

Finally, I have had issues with FireFox and IE not appearing to download the very latest versions of my Silverlight apps from my webserver. I know the latest version is online, but sometimes the previous version appears in my browser. I'm not quite sure exactly why this is happening yet.

Thursday, 6 March 2008

Converting SilverNibbles to Silverlight 2.0 beta 1

Everyone knows that Silverlight 2.0 beta 1 was released yesterday, and already DotNetKicks is awash with information about it, so I'll get straight to business.

This beta brings lots of really cool stuff we have wanted for a long time, controls being the most obvious, as well as layout containers and the ability to apply themes. Also I really like the look of the new .xap format allowing much easier deployment.

My task was to update one of my codeplex projects - SilverNibbles, to use Silverlight 2.0 beta 1. SilverNibbles was my first ever Silverlight app, ported from a WinForms game in just a couple of evenings after downloading the Silverlight 1.1 alpha. It is even featured on the gallery on the Silverlight website, although my complete ineptitude at graphic design means that it looks dreadful compared to all the slick applications alongside it.

My first mistake was installing the Silverlight 2.0 beta 1 SDK. You should just install the Silverlight 2.0 beta 1 tools for VS2008 which includes the SDK. I ended up having to uninstall the SDK before I could install the VS2008 tools.

Next task was to load the project into Visual Studio. I didn't want to create a new project and copy files in, so it required a fair amount of hacking around with the csproj file in a text editor, after making a new 2.0 project which I could use to compare differences. The two web pages most helpful to me during this process were Converting Silverlight 1.1 Alpha projects to Silverlight 2 Beta 1 and the breaking changes for Silverlight 2 Beta 1 page on MSDN. Eventually I had the project set up so it would compile to a .xap file.

After this, there were plenty of compile errors I had to work my way through. The one that held me up the longest was that the [Scriptable] attribute is now replaced by [ScriptableType] and [ScriptableMember]. Also, some event handling functions had changed their function signatures, meaning that my events were no longer connected up to the XAML properly.

The biggest change that had to be made was to completely rework the way that my UserControls were constructed. First of all, the XAML had to be set to compile instead of embedding as a resource. Second, the XAML had to be altered to be a UserControl at the top level rather than a Canvas. Third, the code behind needed to be a partial class that inherited from UserControl. Fourth, I needed to call InitializeComponent in the constructor and use the auto-generated member variables rather than loading from an embedded resource stream and using FindByName.

My PauseControl had a lot of errors in the code, but thanks to the new layout containers in Silverlight 2.0 beta, I could just delete the sizing code. I simply put a text-block inside of a border control and resizing was handled automatically.

One thing that has not improved at all in the transition to 2.0 beta is the error reporting. Errors are as vague as ever. Parse errors rarely point you to the true source of the problem. I got a "catastrophic failure" message simply because a Storyboard.TargetName was wrong.

I eventually got my application compiling and running using the auto-generated test page, and here I ran into another strange bug. My snakes were no longer appearing to move. I traced this down to the fact that I was now modifying the PointsCollection of a polyline rather than giving an entirely new set of points to the polyline every time. I tried various functions such as InvalidateLayout, InvalidateMeasure, UpdateLayout on the polyline to persuade it to redraw itself but nothing worked. In the end I found the following solution:

polyline.Points = polyline.Points;

This did the trick nicely, although its not exactly elegant code!

The next hurdle was that my HTML page that hosted the application no longer worked. Thankfully, the new .xap format makes things a lot easier, and eventually I got my new 2.0 beta edition of SilverNibbles running without any need for external js files.

There is one outstanding bug though, that I can't seem to get the keyboard focus to go to my Silverlight control in FireFox, although it works in IE. I'm sure this used to work with the previous version of Silverlight, but I don't know what I can do to fix this. Any javascript gurus got any suggestions for me? Here's the code:

var silverlightControl = document.getElementById('SilverlightControl');
silverlightControl.Content.SilverNibbles.NewGame(players);
silverlightControl.focus();

The final obstacle was getting it uploaded to my web server. The game never appeared. Eventually I figured out that I needed to add a new MIME type for the .xap extension: application/x-silverlight-app. So finally it is ready to go and you can play the SilverNibbles game online.

Next up is to begin properly working on Silverlight Audio Player after too many issues with alpha 1.1 put this on hold.

Friday, 22 February 2008

Vista SP1

I installed Vista SP1 on my PC at home earlier this week. It took an hour to install.  I didn't notice any obvious improvements or changes at first. Perhaps it boots a bit faster now, but that kind of thing is very subjective unless you have bothered to time it beforehand.

However, yesterday I found the first real improvement. I had been having problems saving my game in Football Manager 2006. It would take several minutes to save the 200Mb file and would regularly fail to save. Sometimes I would have to attempt to save the game 5 times in a row before it would work. The good news is, that since installing Vista SP1, I have had no errors saving, and the saving is much, much faster (less than 30 seconds now). Its always nice to see some kind of tangible improvement after installing a service pack.

Friday, 15 February 2008

There is no Spoon

And now since I'm in the mood for writing some XAML, here's something really silly. My 2 year old son always throws his spoon in the bin along with his empty yoghurt pot, which has meant we are regularly buying more spoons. So here is a really useful XAML "No Spoons" sign for the bin. I 'designed' the spoon icon in Blend, and then used a transform group to get it into the right place.

Here's the code:

<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
  <Canvas Canvas.Left="20" Canvas.Top="20">
    <Rectangle Width="180" Height="200" Fill="White" RadiusX="5" RadiusY="5" />      
    <Canvas>      
      <Path Fill="#FF000000" Stroke="#FF000000" Data="M438.66803,130.33333 C421.33499,120.1762 422.00165,96.176278 422.00165,96.176278 427.00179,58.843133 452.66745,63.333794 460.00086,94.666778 461.00102,116.50951 455.41396,118.92027 446.00105,130.00013 L450.41981,208.7423 C446.16375,210.81869 441.91328,210.84422 437.66793,209 z" StrokeThickness="2"/>      
      <Canvas.RenderTransform>      
      <TransformGroup>      
      <TranslateTransform X="-350" Y="-60" />      
      <RotateTransform Angle="-45" CenterX="100" CenterY="100" />      
      <ScaleTransform ScaleX="0.75" ScaleY="0.75" />      
      <TranslateTransform X="25" Y="15" />      
      </TransformGroup>      
      </Canvas.RenderTransform>      
      </Canvas> 
      <Canvas Canvas.Left="10" Canvas.Top="10">     
      <Ellipse Height="150" Width="150" Stroke="Red" StrokeThickness="15" />      
      <Line StrokeThickness="15" Stroke="Red" X1="25" Y1="125" X2="125" Y2="25" />      
    </Canvas> 
    <TextBlock Canvas.Top="160" Canvas.Left="30" Text="No Spoons" FontFamily="Arial Black" Foreground="Black" FontSize="20"  />     
  </Canvas>      
</Canvas>

And here's what it looks like:

image

XAML Star Rating

And here's another quick XAML file, this time for star ratings like you see on many websites. By the way, I've been fighting with blogger to try to display code nicely, but it seems to insist on truncating it, and ignoring any styling I try to put on it. I'm hoping to move to another blog platform before too long, but if anyone knows of a simple way to make blogger display formatted code, please let me know.

<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
  <Canvas Canvas.Left="20" Canvas.Top="20">
    <Rectangle Width="200" Height="50" Fill="White" RadiusX="5" RadiusY="5" />
    <Canvas Canvas.Left="5" Canvas.Top="20">
      <Path Stroke="#000080" Fill="#FFFF00" StrokeThickness="3" StrokeStartLineCap="Round" StrokeEndLineCap="Round" StrokeLineJoin="Round" Data="M 0,0 l 10,0 l 5,-10 l 5,10 l 10,0 l -7,10 l 2,10 l -10,-5 l -10,5 l 2,-10 Z" />
    </Canvas> 
    <Canvas Canvas.Left="45" Canvas.Top="20">
      <Path Stroke="#000080" Fill="#FFFF00" StrokeThickness="3" StrokeStartLineCap="Round" StrokeEndLineCap="Round" StrokeLineJoin="Round" Data="M 0,0 l 10,0 l 5,-10 l 5,10 l 10,0 l -7,10 l 2,10 l -10,-5 l -10,5 l 2,-10 Z" />
    </Canvas>
    <Canvas Canvas.Left="85" Canvas.Top="20">
      <Path Stroke="#000080" Fill="#FFFF00" StrokeThickness="3" StrokeStartLineCap="Round" StrokeEndLineCap="Round" StrokeLineJoin="Round" Data="M 0,0 l 10,0 l 5,-10 l 5,10 l 10,0 l -7,10 l 2,10 l -10,-5 l -10,5 l 2,-10 Z" />
    </Canvas>
    <Canvas Canvas.Left="125" Canvas.Top="20">
      <Path Stroke="#808080" Fill="#C0C0C0" StrokeThickness="3" StrokeStartLineCap="Round" StrokeEndLineCap="Round" StrokeLineJoin="Round" Data="M 0,0 l 10,0 l 5,-10 l 5,10 l 10,0 l -7,10 l 2,10 l -10,-5 l -10,5 l 2,-10 Z" />
    </Canvas>
    <Canvas Canvas.Left="165" Canvas.Top="20">
      <Path Stroke="#808080" Fill="#C0C0C0" StrokeThickness="3" StrokeStartLineCap="Round" StrokeEndLineCap="Round" StrokeLineJoin="Round" Data="M 0,0 l 10,0 l 5,-10 l 5,10 l 10,0 l -7,10 l 2,10 l -10,-5 l -10,5 l 2,-10 Z" />
    </Canvas>
  </Canvas>
</Canvas>

And this is what it looks like:

XAML Star Rating

XAML RSS Icon

I haven't had the time to blog much recently, but I thought I would just share a quick RSS Icon I made in XAML recently:

<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" >
  <Canvas Canvas.Left="20" Canvas.Top="20">
    <Rectangle Width="50" Height="50" Fill="Orange" RadiusX="5" RadiusY="5" />
    <Canvas Canvas.Left="-1" Canvas.Top="1">
      <Ellipse Width="10" Height="10" Fill="White" Canvas.Left="10" Canvas.Top="30" />
      <Path Stroke="White" StrokeThickness="5" StrokeStartLineCap="Round" StrokeEndLineCap="Round" Data="M 15,20 a 15,15 90 0 1 15,15" />
      <Path Stroke="White" StrokeThickness="5" StrokeStartLineCap="Round" StrokeEndLineCap="Round" Data="M 15,10 a 25,25 90 0 1 25,25" />
    </Canvas>
  </Canvas>
</Canvas>

Here's what it looks like:

XAML RSS Icon

Obviously if you are a graphic designer you could give it some cool gradient effects to make it look 3D.