Friday 31 August 2007

Visual Studio 2005, Visual Studio 2008 co-existing peacefully

If you want Visual Studio 2005, and Visual Studio 2008 to co-exist peacefully for the same projects, this might help you out.

I would recommend you minimize the impact of the conversion wizard by following this procedure.

1) Make a copy of your existing solution file (i.e. to have VS2005 and VS2008 version of the solution file, e.g. MySolution.sln and MySolutionOrcas.sln)

2) Open up the new solution, and choose not to convert any projects in the solution

This means you will be able to develop using Visual Studio 2008, and Target .NET Framework 2.0, but still be able to use Visual Studio 2005 (if required), or if other project members haven't moved across to Orcas yet.

Finally this method should also work with TFS meaning, you can develop with Orcas but your build server will know no better (I haven't tested this yet, but I'm pretty sure it will be OK as I have tested it with msbuild)

If you run into trouble you can do it manually:

For each project file in the solution change the first line from this:


<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">


to this:


<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="2.0">


The important part is the ToolsVersion="2.0", this will mean that VS2008 will not attempt to convert this project, and will target framework 2.0 for you :)

Finally once you have modified all the project files, you can open the new solution file (MySolutionOrcas.sln) in Visual Studio 2008 (Orcas Beta 2)

You can now allow Orcas to convert your solution (and it will not attempt to convert any of the other projects to Visual Studio 2008)

Silverlight and Google Gears

Logically it makes sense that Google Gears and Silverlight would be able to talk to each other.

Infact here is an interesting article where this has been done.

I will even find some time, to do this myself at some point, as I think it would be an interesting thing to do.

However, I can't help thinking we wouldn't need to think about using Google Gears, if Microsoft provided more than 1MB of Isolated Storage per application.

Please, Please, Please increase the Isolated Storage Limit (and as per my previous post on Offline Storage), please put some work into supporting Offline Silverlight.

Thursday 30 August 2007

My Server is Back

Yay

Hosting Server is down

My hosting server is down at the moment, and won't be back up until later today.

This means you won't be able to view any of the online demo's or download the source just now for any of the samples.

Hopefully it will be back up this evening

Sorry

Tuesday 28 August 2007

Orcas Framework Multi-Targeting

Within Visual Studio Orcas, the concept of framework targeting is introduced.

You can target any project or solution to any of the following versions of the .NET Framework.

.NET Framework 2.0
.NET Framework 3.0
.NET Framework 3.5

Visual Studio 2008 (Orcas) will always use MSBuild Toolset 3.5, which means that regardless of your targeted framework, and even though the code is compatible with .NET Framework 2.0, it will be generated using the latest C#, VB Compiler (not the compiler that shipped with 2.0).

This means that you can use features that produce IL compatible with .NET Framework 2.0 (e.g. Automatic Properties), but you can't use incompatible features (e.g. LINQ).
The code you deploy will be fully compatible, and will reference the dependant assemblies (system, system.data) that shipped with 2.0, but the IL will be produced by the latest compiler.

There is a word of caution here, if you use new language features you will not be able to continue to use Visual Studio 2005 (or existing TFS Build Server, MSBuild (for .NET 2.0)), you also cannot use Websites (not Web Applications), as this is compiled on the website.

If you are paranoid about beta code, then you should therefore develop in Orcas (ignoring new language features, and build in VS2005, or using the earlier version of MSBuild).

Visual Studio 2008 will also stop you from using the features of an earlier framework, until you retarget the framework (which you can do at anytime, (Right Click on Project, Select Properties, Application Tab, Target Framework)
). The support in the IDE is so good, that it will even hide web control specific to .NET Framework 3.5 (e.g. LINQDataSource and ListView).

There is only one gotcha to really be aware of, if you upgrade a solution to Visual Studio (2008), you will need to prat around with the solution to make it work again in Visual Studio 2005 (i.e. the version number in the solution file). This is a bit of a pain, but not the biggest deal in the world (since this is the only change).

Sunday 26 August 2007

How to make a Button in Silverlight 1.1

In my button we will change the color of the canvas in on mouse hover, and allows you to implement the click logic at the TODO.

You can use this code for your own buttons.

The important points are:

MouseEnter - When we hover over the button
MouseLeave - When we stop hovering over the button
MouseLeftButtonDown - When you hold the mouse left button down
MouseLeftButtonUp - When you release the mouse left button.

A click is only considered a click, when you are hovered over the button, and the MouseLeftButtonUp.

On MouseLeftButtonDown you need to capture the mouse input, and release the mouse capture when finished (so mouse input can be capture by other objects at another time, you can only capture mouse input if no other object has captured mouse input).

Finally we do a final cleanup (if necessary) on the canvas to ensure we have released the mouse capture.

One final thing to note, within the XAML for the canvas we use the Cursor attribute to define the mouse cursor to use.

Go Enjoy, and make Buttons (whilst you can), before Microsoft makes it even easier for us :)

Here is the XAML for my Button:



<Canvas xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="550"
Height="40"
Background="DarkBlue"
MouseEnter="MenuItem_MouseEnter"
MouseLeave="MenuItem_MouseLeave"
MouseLeftButtonDown="MenuItem_MouseLeftButtonDown"
MouseLeftButtonUp="MenuItem_MouseLeftButtonUp"
Cursor="Hand"
>
<TextBlock x:Name="tbMenuText" Foreground="White" FontWeight="ExtraBold" FontSize="28"></TextBlock>
</Canvas>


Here is the C# for my Button:



using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace MySilverlightProject.SkyEPG
{
public class MenuItem : Control
{
public MenuItem()
{
System.IO.Stream s = this.GetType().Assembly.GetManifestResourceStream("MySilverlightProject.SkyEPG.MenuItem.xaml");
implementationRoot = this.InitializeFromXaml(new System.IO.StreamReader(s).ReadToEnd());
tbMenuText = implementationRoot.FindName("tbMenuText") as TextBlock;

// Set the root leave
implementationRoot.MouseLeave += MenuItem_OnRootLeave;
}

#region properties
// private members
FrameworkElement implementationRoot;
private TextBlock tbMenuText;

/// <summary>
/// Text
/// </summary>
public string Text
{
get
{
return tbMenuText.Text;
}
set
{
tbMenuText.Text = value;
}
}
#endregion

#region Mouse Handling
// By Default mouse over is false and mouse down is false
bool mouseOver = false;
bool mouseDown = false;

/// <summary>
/// On enter set the color to yellow
/// </summary>
/// <param name="o"></param>
/// <param name="e"></param>
protected void MenuItem_MouseEnter(object o, EventArgs e)
{
// Get the menu item
Canvas menuItem = (Canvas)o;

// We have a mouse over
mouseOver = true;

// Set the background color to gold, text color to dark blue
menuItem.Background = new SolidColorBrush(Color.FromArgb(255, 255, 215, 0));
tbMenuText.Foreground = new SolidColorBrush(Color.FromArgb(255, 0, 0, 139));
}

/// <summary>
/// On leave, set the color back to Dark Blue
/// </summary>
/// <param name="o"></param>
/// <param name="e"></param>
protected void MenuItem_MouseLeave(object o, EventArgs e)
{
// Get the menu item
Canvas menuItem = (Canvas)o;

// Set the background color to Dark Blue, text color to white
menuItem.Background = new SolidColorBrush(Color.FromArgb(255, 0, 0, 139));
tbMenuText.Foreground = new SolidColorBrush(Colors.White);

// No Mouse Over
mouseOver = false;
}

/// <summary>
/// Mouse Left Button Down
/// </summary>
/// <param name="o"></param>
/// <param name="e"></param>
protected void MenuItem_MouseLeftButtonDown(object o, MouseEventArgs args)
{
// Mouse Down
mouseDown = true;

// Get the menu item
Canvas menuItem = (Canvas)o;

// Capture the Mouse
menuItem.CaptureMouse();
}

/// <summary>
/// Mouse Left Button Up
/// </summary>
/// <param name="o"></param>
/// <param name="e"></param>
protected void MenuItem_MouseLeftButtonUp(object o, MouseEventArgs args)
{
// Get the menu item
Canvas menuItem = (Canvas)o;

// Release the mouse capture
menuItem.ReleaseMouseCapture();

// Check if we have a click (mouse over, and mouse down)
if (mouseOver)
{
// TODO: Implement Click Logic Here
}

// No Mouse Down
mouseDown = false;
}

/// <summary>
/// When the mouse leaves the root visual we lose the capture - reset the state
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
protected virtual void MenuItem_OnRootLeave(object sender, EventArgs args)
{
// Clean Up
if (mouseOver || mouseDown)
{
// Release Mouse Capture
ReleaseMouseCapture();
mouseDown = false;
mouseOver = false;
}
}
#endregion
}
}

Making Buttons

Although the button has been implemented in the Silverlight Sample Controls Toolkit, I don't think is particularly useful until Silverlight supports templating.

You could use the ButtonBase class and implement a new control which inherits ButtonBase, however I feel you are avoiding writing code, and you would be better to understand a button on your own. In a sense it is almost simpler just to implement a button yourself.

Therefore in the next post i will discuss how to make your own button (with code), and why we do things a certain way. This is good knowledge to have even thought its something we will not worry about in the future. The reason we will not worry about it, as we will just use a templated button from the standard set of controls.

Waffle Over, Lets Make A Button.

Thursday 23 August 2007

Partner Conference Silverlight Site

This page has some very cool silverlight on it(version 1.0)

The little tree thing is particularly cool :)

http://members.microsoft.com/partner/digitalwpc/

Wednesday 22 August 2007

Tafiti

Microsoft has released a new sample website in Silverlight 1.0 called Tafiti

I recommend you look at the site, as it gives you a good clue on how Microsoft are doing certain things.

When I looked at the site, there was a nice little Textbox which perked up my interest?

When you look at the back end javascript, it is very clear they are using an Html Textbox with some pretty Xaml around it.

Its great that we can steal that techinique (even in Silverlight 1.1), however it does seem to indicate that we won't see any new sample controls for a while.

Well Done Microsoft, its a great sample site and we will be able to use a lot from it.

It would be better if you provided a 1.1 version as well, which would save us some porting, but definately good enough for me.

Sunday 19 August 2007

Silverlight Downloader which works both with file system and online mode

One of the issues with the 1.1 Alpha Refresh for Silverlight is that if you attempt to use the downloader object when you are working from the local file system, it will throw up an exception. This forces you to work under IIS.

It is nice to work directly from the file system and skipping out IIS, but you want to develop your applications to use the downloaders from the beginning.

I have therefore created a little downloader which can be used for media elements (will not work for xaml, or xml documents), but will work great for images and videos.

This downloader class can work in multiple modes, if you are working under a file system, then it will just set the image, video sources directly for you (and won't use the downloader), if you specifiy a ZipFile it will download the zipfile for you (using the downloader (unless working in local mode, where it will use the local path and ignore the zip)), finally if you have multiple files to be downloaded (and don't want to use a zip file (large number of files to be displayed, and you wish to show them whenever they have downloaded, then this will also work for you).

The class declaration is below:



using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;

namespace Roskakori.Silverlight.Common.Controls
{
public class SchemeSensitiveDownloader
{
#region properties
private Downloader _mediaDownloader;
public string ZipFile { get; set; }
public List<FileDetails> Files { get; set; }
#endregion

#region Constructors
/// <summary>
/// Constructor
/// </summary>
public SchemeSensitiveDownloader()
{
// Initialise
Files = new List<FileDetails>();
}
#endregion

#region events
public event EventHandler DownloadCompleted;
public event EventHandler FileDownloadCompleted;
public event EventHandler FileDownloadProgressChanged;

/// <summary>
/// Download Completed
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void _mediaDownloader_Completed(object sender, EventArgs e)
{
// Check if we have anything attached to the event
if (FileDownloadCompleted != null)
{
// Raise the File Downloaded Completed Event
FileDownloadCompleted(sender, e);
}

// Get the sender as a downloader
Downloader downloader = (Downloader)sender;

// Check if we have anything attached to the event
if ((DownloadCompleted != null) && ((downloader.Name == "zip" || (Convert.ToInt32(downloader.Name) == Files.Count - 1))))
{
// Raise the File Downloaded Completed Event
DownloadCompleted(this, new EventArgs());
}
}

/// <summary>
/// Download Progress Changed
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void _mediaDownloader_DownloadProgressChanged(object sender, EventArgs e)
{
// Check if we have anything attached to the event
if (FileDownloadProgressChanged != null)
{
// Raise the File Downloaded Progress Changed Event
FileDownloadProgressChanged(sender, e);
}
}
#endregion

/// <summary>
/// Download the files apporiately either as a zip, individually, or as one
/// </summary>
public void Download()
{
// Loop through all the files if we have a zip file, or if local
if (string.IsNullOrEmpty(ZipFile) || (System.Windows.Browser.HtmlPage.DocumentUri.Scheme.ToLower() == "file"))
{
// Initialise
int i = 0;

// Loop through all the files
foreach (FileDetails file in Files)
{
// File Download
if ((System.Windows.Browser.HtmlPage.DocumentUri.Scheme.ToLower() == "file") && (FileDownloadCompleted != null))
{
// Raise the File Downloaded Completed Event
FileDownloadCompleted(file, new EventArgs());

// Check if we have anything attached to the event
if (DownloadCompleted != null)
{
// Raise the File Downloaded Completed Event
DownloadCompleted(this, new EventArgs());
}
}
else if (FileDownloadCompleted != null)
{
// Initialise the downloader
_mediaDownloader = new Downloader();

// Set an identifier
_mediaDownloader.SetValue(Downloader.NameProperty, i.ToString());

// Add the event listener
_mediaDownloader.Completed += new EventHandler(_mediaDownloader_Completed);
_mediaDownloader.DownloadProgressChanged += new EventHandler(_mediaDownloader_DownloadProgressChanged);

// Open the downloader
_mediaDownloader.Open("GET", new Uri(file.Source, UriKind.RelativeOrAbsolute));

// Send the request
_mediaDownloader.Send();
}

// increment
i++;
}
}
else
{
// Initialise the downloader
_mediaDownloader = new Downloader();

// Set an identifier
_mediaDownloader.SetValue(Downloader.NameProperty, "zip");

// Add the event listener
_mediaDownloader.Completed += new EventHandler(_mediaDownloader_Completed);
_mediaDownloader.DownloadProgressChanged += new EventHandler(_mediaDownloader_DownloadProgressChanged);

// Open the downloader
_mediaDownloader.Open("GET", new Uri(ZipFile, UriKind.RelativeOrAbsolute));

// Send the request
_mediaDownloader.Send();
}
}

public class FileDetails
{
public string Source { get; set; }
public Control AssociatedControl { get; set; }
public string Filename
{
get
{
var uriParts = Source.Split('/');
return uriParts[uriParts.GetUpperBound(0)];
}
}
}
}
}


If you wish to see it in action you can look at Mix07UK Sample Site. Both an online demo and source is available.

Friday 17 August 2007

Javascript Intellisense Bug in Orcas Beta 2

I've been preparing for the nugget i am doing in Birmingham next month at NxtGenUg (I will follow up details on a later post).

I've been working on the ins and outs of intellisense for Javascript.

For some reason whenever i split code between files, intellisense doesn't seem to like it so much.

So for example if i have a person object function, and a test function in the same class, intellisense will work, and i can see the FirstName and Surname properties.



<script type="text/javascript">
function Person(firstName, surname)
{
/// <summary>This is a person class</summary>
/// <param name="firstName" value="string">The first name of the person e.g. Johnny</param>
this.FirstName = firstName;
this.Surname = surname;
}

function Test()
{
var newPerson = new Person("fred", "jones");
}
</script>



If however i move the Person class from my aspx file into a seperate .js textfile, intellisense breaks.



<script type="text/javascript" src="Person.js"></script>

Cambridge User Group Launch (Evening of September 18th)

Oh yes!

I know have been a little quiet the past few days, and here is why:

We have just launched the Cambridge Region of NxtGenUG.

We have Mike Ormond doing a talk on Silverlight (full 60 minutes), and One of the Microsoft Researchy Guys (to be confirmed whom), doing a talk on F#, We also have Pizza, and We have Swag (free stuff).

It's going to be an amazing event, so please come along. You do need to register so we can plan for pizza and for the security guy at MS Research.

The group will be held at Microsoft Research in Cambridge (Thanks Guys).

After the launch event we will be holding one session every month, and we have some great sessions in the pipeline

Register Here (registration is free, come along and get free pizza):

Sunday 12 August 2007

Silverlight Mix UK Sample Site (First Version)

I've now posted up my Mix07 UK Silverlight Sample Site.

This is the first version of an Event Registration System written in Silverlight.

You can click here if wish to view the application online (please be patient for the videos to download, you will probably want to refresh the browser after the videos have downloaded, I haven't smoothed up this process with a downloader yet).

You can also download the source from here.

In future posts, I will explain why i have done things certain ways and what my thoughts were during development.

This sample will show some of the following things in action:

Loading of an Xml using XmlReader
Video Button Control (MediaElement, ButtonBase, VideoBrush)
LINQ
Seperation of UI, Business and Data

In the future the sample will be extended to use the following

1) Expand to show Day 2's schedule
2) On Click of the Video Button, bring up Session Information, and show a Video Clip in a main media player
3) Speaker Information Page
4) Pulling the XML from a web service and storing in isolated storage
5) Use of a downloader for downloading the Videos
6) Use the base code to perform event selection
7) Funky Background Music

Hopefully you might find this sample useful, and I hope to expand this to show how to perform various tasks in Silverlight. This will become a bit of a working reference application for me.

This sample should show that in the world of Silverlight we can do great things, and produce much more interesting websites.

Saturday 11 August 2007

Looping a Media Element in Silverlight

I answered this post earlier today, because there is no support for mediatimeline in silverlight, we have to code in looping of media elements.

All you really need to do is call play on the mediaended event (remember to hook in the event in the xaml)

code below:



protected void myMediaElement_MediaEnded(object sender, EventArgs args)
{

// Replay the video

MediaElement video = (MediaElement)sender;video.Position = new TimeSpan(0);
video.Play();

}

Friday 10 August 2007

Silverlight and Bandwidth Detection

Somebody wanted to know in the Silverlight forums, if you could do automatic bandwidth detection, and grab a video based on the calculated bandwidth.

This got me thinking........

If you use a downloader to download a known image, you would be able to calculate approximately the bandwidth of the user based on the time taken to download that known image size. You can then use that bandwidth calculatation to download the approriate media automatically,

I will probably knock up a sample in the next couple of weekes, when i have finished the little app I am doing just now (still got another week or so before i will publish it).

In the meantime you can get information about downloaders from silverlight quickstarts.

Or feel free to get in touch

Thursday 9 August 2007

Silverlight in the UK

It would be interesting to know who in the UK is messing around with Silverlight?

Are we all developing stuff for fun or is anyone doing commercial development just now?

Would also be interested in knowing what sort of stuff folks in the UK are developing?

Are there many of us?

Anybody going to Mix in London?

Silverlight 1.0, Visual Studio 2008 (Orcas), Sql Server 2008 (Katmai) Release Dates

Visual Studio 2008 (Orcas)

RTM - End of this year (Expected in November)
Launch - February 27th 2008

SQL Server 2008 (Katmai)

RTM - May 9th 2008
Launch - February 27th 2008 (Marketing Launch Only)

Windows Server 2008

RTM - End of this year (Expected in November)
Launch - February 27th 2008

Silverlight

Silverlight 1.0 - Unknown but Scott Guthrie did say it would be end of this Summer. The real question is how long does Scott Guthrie think a Summer lasts, if he is a pessimist (we should expect it very soon), if he is an optimist (not so soon).
The current RC expires November, so it is likely to be before then.
I am going to take a stab in the dark, and I reckon they might do a surprise release at Mix07 in the UK on September the 11th. Especially since Mr Guthrie himself will be there (and I thought I read Tim Sneath would be there also). However this is my humble guess, and if any Microsoft bods would like to give me the actual date it would be most appreciated.

Silverlight 1.1 - Uknown not expected until 2008

Wednesday 8 August 2007

Silverlight Offline Mode

I just recently read in the Silverlight Architecture Overview that "Silverlight is designed for Web page content that is connected to its host (it will not work offline), that deeply engages the user, and that can render on any browser."

Hmmn, doesn't work offline. I think that is not the greatest idea in the world as the power we can have with Silverlight and Isolated Storage together to produce funky little applications. Surely this is not right!

So I have done a little test by switching Internet Explorer to Work Offline, and see if my apps run.

Surprise, Surprise they do run, however they don't seem to be able access video etc.

So for example in my Rotating Video Picture Board if you connect to it offline mode, the application will work (and rotate), however the video doesn't run.

I must experiment a little more, for example if I access media and put it in Isolated Storage and then download it, will it work?

Also I am going to assume that embedded resources will work (but I need to check this)?

However I think a better option is to plea to Microsoft that being able to run offline (including cached video), is a good option and will bring a lot of power to Silverlight Applications.

Monday 6 August 2007

Anonymous Types

I am going to be quite short in this article because I think Daniel Moth's article can explain anonymous types better than i can. However to be complete i will give a short explanation.

Anonymous Types as the name suggests allows you to create a strongly typed object without declaring the class in the first place (this does rely strongly on local variable type inference and Object Initalisers).

For example:



var mailingListSubscriber = new {emailAddress="a@a.com", spamMe=true};


The cool thing about the example above is that mailingListSubscriber now has full intellisense within Visual Studio. At first I thought that was pretty amazing but if you think about what is happening behind the scenes it makes sense.

The anonymous type is not a latebound object, it is a strongly typed object which is autogenerated behind the scenes by the C# Compiler (open up ildasm and have a look for yourself). This means in reality there is no difference (to the CLR) between an anonymous type and a normal type.




Anonymous Types are restricted in the fact that they can only be used within the scope of a local method. This isn't a restriction imposed by the CLR (as i said the CLR doesn't care), but by the C# Compiler. This is a good restriction though, otherwise us developers would end up writing some unmaintainable crazy nonsense code. So thank you C# team for protecting us (from ourselves).

Is an autogenerated, local scoped, undeclared class useful? Damn straight it is, it is one of the many key features that makes LINQ work. I doubt you will ever use Anonymous Types outside of LINQ queries but boy are they useful there (You will notice anonymous types when using the select part of a LINQ query). Using Anonymous Types within LINQ allows you to focus on interacting with the data (in a safe and strongly typed manner) and forget about unneccasary object declarations, or worry about runtime issues with untyped objects.

I will no doubt discuss LINQ in more detail in one of my future blog posts.

Again thanks to Daniel Moth at Microsoft for keeping me straight as I voyage around the new features.

Update to Intellisense Bug

Last week I blogged that Silverlight XAML Intellisense was broken when i used custom controls in Visual Studio 2008 (Orcas Beta 2).

Microsoft were very cool about it. Microsoft got back to me on the monday night (which was very fast), however i have been very slow to blog the results. Unfortunately I am neither as fast or as cool as Microsoft.

Essentially this is a known bug. And the reason is they used the Xml Editor rather than the Cider Editor (which they haven't had time to implement yet). This is very understandable as we are getting very very early previews of this stuff. Which means not all features are implemented. They will endeavour to fix it, but it is unlikely to be fixed until they do a release with the Cider Editor.

Thanks to Scott Guthrie, and Sam Spencer for being so quick.

Local Variable Type Inference

This is a great little feature which is now available in C# 3.0.

Local Variable Type Inference allows you declare a strong typed variable without specifying the type.

For Example:


var myList = new List<string>{"Hello", "World"};

At first I was a little sceptical about this feature. As any good programmer knows it is better and cleaner to know your types etc. From reading the code its not always obvious what the type of the variable is.

However this is nice in theory but in practise it is absolutely sweet, and saves you verbose local declarations.

There are some key points to note:


  • This is NOT equivalent to using a late bound object

  • Local Variable Type Inference is equivalent to typing the full declaration yourself (the C# compiler will perform the subsitution for you).

  • You must initialise with a value (e.g. var myString = "Hello";) so the compiler can infer the type. You cannot skip initalisation (e.g. var myString;) as this will produce a compiler error.

  • You cannot switch types (i.e. initialise with a string, and then assign an integer, you must follow the same rules as fully declared types as they are equivalent)

  • You can only use Local Variable Type Inference for a locally declared variable scoped within a method (as the name might suggest




As I say although I initially had reservations about this feature, I find that when you are using enumarable types, or just instatiating an object with a large declaration (dictionaries etc), using the var keyword is more readable than double declarations.

Finally thanks to Daniel Moth for helping me out with my worst subject (whioh is giving things the correct name, Doh!)

Next post will be on Anonymous Types (and what they actually are)

Silverlight and LINQ over Xml (XLinq)

I have been developing a very cool little app (which will be available in the next few weeks) and have been hit with a little snag.

Although I know that XLinq will be available in Silverlight, it currently is not available to use.

This left me with the dilemma of either using XmlReader to process the XmlDocument (this is the only supported method of parsing XML in Silverlight), or use a Web Service which returns the required objects and not use XML client side.

After much thought, I have decided it is better to download the XML and parse client side (and not go down the Web Service route). I can always rewrite the XML layer later on to use XLinq.

The reason i have decided to stick with my orginal plan of downloading the XML is to make effective use of caching, and to be able to give offline support.

I hope my thoughts on this might help you clarify your own thoughts when facing a similar problem.

Its a shame as the XLinq stuff is really neat, and I had a lot of fun playing with it last night. It really is a big improvement over using XmlReader or using the DOM (XmlDocument etc).

I will probably do a post about XLinq later on.

Thursday 2 August 2007

MediaElement Etc

Yesterday I posted a post on how to integrate silverlight with the ActiveX Media Player.

Just to clarify this post is in response to somebody who wished to integrate directly with the Media Player.

This is not how i would recommend doing this (as you run into cross browser compatibility issues). I would always recommend where possible using the MediaElement. If you do however wish to integrate with the ActiveX Media Player, that is how you would do it.

Soapbox over

Wednesday 1 August 2007

Interacting Silverlight (1.0) and ActiveX Media Player

Here is the Html



<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<!-- saved from url=(0014)about:internet -->
<head>
<title>Silverlight Project Test Page </title>

<script type="text/javascript" src="Silverlight.js"></script>
<script type="text/javascript" src="TestPage.html.js"></script>
<style type="text/css">
.silverlightHost { width: 640px; height: 480px; }
</style>
<SCRIPT LANGUAGE="JavaScript">
// Browser sniff -- the following code does a very simple browser check and rates the
// browser as either Internet Explorer on a Win32 platform or not, so that we
// know to use the ActiveX model, or the plug-in Model.
var sBrowser = navigator.userAgent;
if ((sBrowser.indexOf("IE") > -1) && (navigator.platform == "Win32"))
{
sBrowser = "IE";
} else {
sBrowser = "nonIE";
}
// end browser sniff

function showClick() // This function is called by the btnShowControls button.
// It sets the ShowControls property of Media Player to true.
{
if (sBrowser == "IE") {
document.MediaPlayer1.ShowControls = true;
} else {
document.MediaPlayer1.SetShowControls(true);
}
}

function hideClick() // This function is called by the btnHideControls button.
// It sets the ShowControls property of Media Player to false.

{
if (sBrowser == "IE") {
document.MediaPlayer1.ShowControls = false;
} else {
document.MediaPlayer1.SetShowControls(false);
}
}

function muteClick() // This function is called by the "Mute" button.
// It toggles the state of the Mute property of the Media Player.
{
var bMuteState;

if (sBrowser == "IE") {
bMuteState = document.MediaPlayer1.Mute;
} else {
bMuteState = document.MediaPlayer1.GetMute();
}

if (bMuteState == true) {
document.myButtons.btnMute.value="Mute";
if (sBrowser == "IE") {
document.MediaPlayer1.Mute = false;
} else {
document.MediaPlayer1.SetMute(false);
}
} else {
document.myButtons.btnMute.value="Un-Mute";
if (sBrowser == "IE") {
document.MediaPlayer1.Mute = true;
} else {
document.MediaPlayer1.SetMute(true);
}
}
}

</SCRIPT>
</head>

<body>
<!-- BEGIN GENERIC ALL BROWSER FRIENDLY HTML FOR WINDOWS MEDIA PLAYER -->
<OBJECT ID="MediaPlayer1" width=160 height=112
classid="CLSID:22D6F312-B0F6-11D0-94AB-0080C74C7E95"
codebase="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701"
standby="Loading Microsoft Windows Media Player components..."
type="application/x-oleobject">
<PARAM NAME="FileName" VALUE="mms://wm.microsoft.com/ms/sbnasfs/wmt/turtle28.asf">
<PARAM NAME="ShowControls" VALUE="0">
<EMBED type="application/x-mplayer2"
pluginspage = "http://www.microsoft.com/Windows/MediaPlayer/"
SRC="mms://wm.microsoft.com/ms/sbnasfs/wmt/turtle28.asf"
name="MediaPlayer1"
width=160
height=112
ShowControls=0></EMBED>
</OBJECT>
<!-- END GENERIC ALL BROWSER FRIENDLY HTML FOR WINDOWS MEDIA PLAYER -->
<div id="SilverlightControlHost" class="silverlightHost" >
<script type="text/javascript">
createSilverlight();
</script>
</div>
</body>
</html>


Here is the XAML




<Canvas x:Name="parentCanvas"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<TextBlock Text="click me" FontSize="50" MouseLeftButtonDown="showClick" Canvas.Top="50"/>

</Canvas>