| Comments

Remember the final moments of the Scott Guthrie keynote presentation at PDC09?  Where Brian Goldfarb came on stage and demonstrated a completed application using a lot of the features of Silverlight 4?  Yeah, that Facebook application.  Well, it’s here now!

Microsoft Silverlight 4 Beta Client for Facebook

Silverlight Client for Facebook - Home view

The Microsoft Silverlight 4 Beta Client for Facebook has been released as a developer preview sample.  In order to use it you must have Silverlight 4 developer builds installed.

NOTE: When you run this application you’ll be installing the developer builds of Silverlight.  When Silverlight 4 releases, unless you are a developer, you’ll likely want to uninstall this plugin and install the released software.  This sample application is being provided as a developer preview to showcase and inspire.

The application is installed as a trusted application and does all the things you’d expect for Facebook.

Status updates:

Silverlight Client for Facebook - Status updates

Drag/drop pictures from your computer to a photo album:

Silverlight Client for Facebook - Add photo

A photo feed view:

Silverlight Client for Facebook - photo feed

Notifications for messages to you:

Silverlight Client for Facebook - notification window

Add a photo to a post using your web camera on your computer:

Silverlight Client for Facebook - Webcamera input

And yes, anyone uploading video to Facebook can be played back in the app as well:

Silverlight Client for Facebook - flash video playback in Silverlight

A lot of cool ways to explore your Facebook information (sorry, no mafia war games…for me that’s a good thing).  You can also see some Outlook integration if you right-click on events that you may have to send an email and such (I don’t have any events in my Facbook account to snapshot).

So what’s NOT in there?

Good question.  At PDC09 you may have seen a few things that I haven’t mentioned yet above.  The chromeless (borderless application) aspect of the application is not in this preview.  This is because the beta of Silverlight doesn’t include that feature right now.  Additionally the plug-in the camera and have it automatically import the pictures is not in this preview as well.  That was implemented using some COM integration and the team just didn’t clean that code up for this preview for the public.

What about source code?

At this time no source code is being provided…and probably won’t be.  I’m not the decision maker on ultimately if it will or not, just my assumption.  The Facebook client is meant to be a working demonstration/inspiration of what one could do with existing services and providing different views into an existing application framework.

How can I install this and will it work on my Mac?

You can play around with the app by visiting the Microsoft Silverlight 4 Beta Client for Facebook app on the Silverlight samples site (which also includes the other sample applications from PDC09).  As a reminder, this is a developer preview build and intended for developers.  You will need to have Silverlight 4 installed on your machine (which is a beta plugin).  The link to the app will direct you where you can get the appropriate download.

Yes, it will work on your Mac (as long as you have an Intel processor version).  When you install the app you’ll see the Apple preferred install guidelines to drag the application to your Applications folder and can navigate to it there or use Spotlight search to find it.

This is a fun little application to navigate your Facebook account.  The team had a good time building it and is excited to share it with others.  Have fun!

| Comments

Below is a list to links of my Windows 7 themes that are based on the Smashing Magazine monthly desktop wallpaper posts.  Simply click on your desired theme pack (you must have Windows 7) and it will run.  These themes all use the default Windows sound themes (minus the start navigation) and are set to rotate every 30 minutes.  You can adjust those settings to your liking after installed.  They also use the 1920x1200 resolution pictures from the post as the maximum/best provided for each author.

I do my best to get them out as soon as Smashing Magazine publishes their final selections.  Hope you enjoy them…I do!

| Comments

As we’ve all been guilty, when you see demonstrations of technologies most of the time the data samples show single table solutions.  When was the last time you’ve developed a single-table system? :-)  Thought so.

In RIA Services demonstrations, most of them have been single-table samples as well.  So how do you go about retrieving relational data (master/details type) with RIA Services?  Here’s an option.  I’m using VS2010, Silverlight 4 and the WCF RIA Services preview using the below sample.  I’m also using the Chinook sample database which has become one of my favorite simpler relational data samples to use.

Creating your project and associated RIA Services

This is easy, create a new Silverlight project and make sure the ‘Enable .NET RIA Services’ link is checked (yes, we know it doesn’t say WCF in that dialog).  My Silverlight application will be a simple button to retrieve artists then show their associated albums.  Here’s my XAML to start:

   1: <Grid x:Name="LayoutRoot" Background="White">
   2:     <StackPanel Width="400">
   3:         <Button Content="Get Artist Information" x:Name="GetArtistButton" Click="GetArtistButton_Click" />
   4:         <StackPanel Orientation="Horizontal">
   5:             <StackPanel x:Name="ArtistsContext">
   6:                 <StackPanel Orientation="Horizontal">
   7:                     <TextBlock Text="Artists: " />
   8:                     <TextBlock Text="{Binding ElementName=ListOfArtists, Path=Items.Count}" />
   9:                 </StackPanel>
  10:                 <ListBox x:Name="ListOfArtists" Width="200" Height="300" DisplayMemberPath="Name" ItemsSource="{Binding}"/>
  11:             </StackPanel>
  12:             <StackPanel x:Name="AlbumsContext">
  13:                 <StackPanel Orientation="Horizontal">
  14:                     <TextBlock Text="Albums: " />
  15:                     <TextBlock Text="{Binding ElementName=ListOfAlbums, Path=Items.Count}" />
  16:                 </StackPanel>
  17:                 <ListBox x:Name="ListOfAlbums" DisplayMemberPath="Title" ItemsSource="{Binding}" Width="200" Height="300"/>
  18:             </StackPanel>
  19:         </StackPanel>
  20:     </StackPanel>
  21: </Grid>

Now on the server side I need to create the associated models and domain services to be consumed.  I’m creating my model using Entity Framework and it looks like this:

Chinook Entity Model

Now I need to create my Domain Service class for that model (remember to build the solution after you create your model so it will show up in the tools).  When we create the Domain Service class be sure to enable the checkbox to generate associated classes for metadata.  Once we finish we have some stub services created for us. 

Using the Domain Service functions

We have GetArtists and GetAlbums functions we can work with.  As an example we can wire up the button click to retrieve a list of artists using the default functions we got:

   1: ChinookContext ctx = new ChinookContext();
   2:  
   3: private void GetArtistButton_Click(object sender, RoutedEventArgs e)
   4: {
   5:     ArtistsContext.DataContext = ctx.Artists;
   6:     ctx.Load(ctx.GetArtistsQuery());
   7: }

But what about when a user clicks on an Artist, we want to show the albums for that artist and not the others.  We need to modify our Domain Service to add a function:

   1: public IQueryable<Album> GetAlbumsForArtist(int ArtistId)
   2: {
   3:     return this.ObjectContext.Albums.Where(a => a.ArtistId == ArtistId);
   4: }

Now we can use that function when a user clicks on an associated artist to populate the album information:

   1: private void ListOfArtists_SelectionChanged(object sender, SelectionChangedEventArgs e)
   2: {
   3:     ListBox theList = sender as ListBox;
   4:     Artist a = theList.SelectedItem as Artist;
   5:     ctx.Albums.Clear();
   6:     AlbumsContext.DataContext = ctx.Albums;
   7:     ctx.Load(ctx.GetAlbumsForArtistQuery(a.ArtistId));
   8: }

Cool.

However, the second event handling for our master-details section for this particular data set seems unnecessary.  After all, why not just include the children data with our initial request if we *know* that we’re doing an explicit master-details view (and our set is not that large relatively speaking).

Modify the metadata classes

Remember the generated metadata classes?  Go back to it now.  You’ll see a definition of the ArtistMetadata that includes this:

   1: public EntityCollection<Album> Albums;

Notice it has an Albums collection property.  Great, so we could just modify our XAML binding to use some element binding and get the Albums property of the SelectedItem right?  Well, not yet.  If we do that, we’ll have no data.  Why is that?  Because we haven’t told RIA Services to perform the necessary additional query to get the data.  Simple add [Include] at the top of the Albums collection:

   1: [Include]
   2: public EntityCollection<Album> Albums;

And that’s what we need.  Now we can add a function to our Domain Service class to get the additional data:

   1: public IQueryable<Artist> GetArtistsWithAlbums()
   2: {
   3:     return this.ObjectContext.Artists.Include("Albums");
   4: }

Now we just need to do some clean up.  We need to change our button click code to get the GetArtistsWithAlbums query now instead of the other one first.

Remove unnecessary code and use binding to help us

Now we can remove the SelectionChanged event handler for our Artists ListBox as well as add some binding commands to our XAML like this:

   1: <Grid x:Name="LayoutRoot" Background="White">
   2:     <StackPanel Width="400">
   3:         <Button Content="Get Artist Information" x:Name="GetArtistButton" Click="GetArtistButton_Click" />
   4:         <StackPanel Orientation="Horizontal">
   5:             <StackPanel x:Name="ArtistsContext">
   6:                 <StackPanel Orientation="Horizontal">
   7:                     <TextBlock Text="Artists: " />
   8:                     <TextBlock Text="{Binding ElementName=ListOfArtists, Path=Items.Count}" />
   9:                 </StackPanel>
  10:                 <ListBox x:Name="ListOfArtists" Width="200" Height="300" DisplayMemberPath="Name" ItemsSource="{Binding}"/>
  11:             </StackPanel>
  12:             <StackPanel x:Name="AlbumsContext" DataContext="{Binding ElementName=ListOfArtists, Path=SelectedItem}" >
  13:                 <StackPanel Orientation="Horizontal">
  14:                     <TextBlock Text="Albums: " />
  15:                     <TextBlock Text="{Binding ElementName=ListOfAlbums, Path=Items.Count}" />
  16:                 </StackPanel>
  17:                 <ListBox x:Name="ListOfAlbums" DisplayMemberPath="Title" ItemsSource="{Binding Albums}" Width="200" Height="300"/>
  18:             </StackPanel>
  19:         </StackPanel>
  20:     </StackPanel>
  21: </Grid>

Notice how the DataContext of my Albums ListBox is now set using element binding to the SelectedItem of the Artists ListBox.  Then the ItemsSource of the ListBox for Albums has a {Binding Albums} command.  This is because our Artists query now includes the associated Album data and we can just reference the property.

Use with caution

While this example shows how easy it can be to have included results in your Domain Service query result, be mindful of when you are using.  For instance if you have a customer database of 1000 customers and you want all orders to be retrieved…it might not be wise to use this particular type of method. 

This presents merely another choice for areas where you may want/need it (i.e., country/state/city) for your application.

You can download the sample solution for the above code snippets here: SilverlightApplication41.zip.  Reminder that you will need to have the Chinook database installed already – it is NOT included with this sample download.

Hope this helps!

| Comments

Happy new year to all!  I hope you enjoyed a safe celebration whether that be playing a board game with friends, toasting the new year with some bubbly, throwing things at Ryan Seacrest on TV, or whatever.

Each quarter, new MVP (Microsoft Most Valuable Professional) candidates are awarded.  January 2010 is the first awards of the year and so I present the new/moved/re-awarded Silverlight specific MVPs:

  • Jeff Prosise – If you aren’t subscribed to Jeff’s blog, stop and do so now.  It’s filled with some great nuggest that are usually on the advanced ‘how’d he do that’ side of things.  Jeff does a good job spelunking the framework and figuring things out.
  • David Yack (@davidyack) – David is a CRM guru and has also written a great Silverlight 3 Jumpstart book (recommended for beginners).  He’s been spending more time with RIA Services for biz/CRM apps lately and been providing great insights into integration uses.  He should blog more :-)
  • Laurent Duveau (@LaurentDuveau) – another re-award for Laurent who keeps cranking out great stuff and helps with the Silverlight Tour in Canada.
  • Laurent Bugnion (@lbugnion) – one of the XAML experts at IdentityMine, Laurent also has written one of the definitive Silverlight reference books – and is one of the nicest guys you’ll meet.
  • Ward Bell (@wardbell) – Ward has some great thoughts on application building for XAML clients and extensive experience with multicolored jackets and general antagonistic views ;-)
  • Page Brooks – organizer of SilverlightContrib and various control development efforts in the community.  Control Wrangler?
  • Rob Eisenberg (@EisenbergEffect) – one of the brains behind Caliburn, an Open Source Silverlight application framework.
  • Andy Beaulieu – have you played a Silverlight game?  If you have, it’s most likely been one of Andy’s :-)
  • Jordan Knight (@jakkaj)– hailing from down under (is that phrase still used?), Jordan does a lot in the Melbourne area around Silverlight community and has a great blog of content.
  • Alessio Leoncini (@aleoncini) – One of our Italian friends that has been doing a lot in working with Silverlight in Italy and spreading the good word! Grazie!
  • Andrew Tokeley – Andrew was one of the developers behind the Buttercup Reader, a completely accessible Silverlight application which is now Open Source.
  • Koen Zwikstra (@kozw) – Have you heard of Silverlight Spy, the indispensible Silverlight debugging tool!?  Koen is the brain behind it.
  • Qing Li is a new MVP in China that has been doing a great amount of work helping the community understand and learn Silverlight development.

Congratulations to all the new/renewed/moved Silverlight MVPs.  I look forward to seeing you at the MVP Summit soon!


This work is licensed under a Creative Commons Attribution By license.

| Comments

I’ve never been so frustrated with a piece of software as I have been with iTunes lately.

NOTE: Yes, I work for Microsoft.  Yes I’m aware they make the Zune.  I’ve got years invested in hardware with iPods, and until someone makes an OEM integration kit as good as what I have, I can’t switch.  Truth be told, from a portable device player, I *do* think the Zune is better.  But let’s just leave that out of this argument for now.

In my home there are roughly 4 iPods floating around.  We have a library of over 5,000 songs both popular and not that are in our digital library.  That digital library is mostly MP3s, mixed with some iTunes purchased songs (although not since Amazon MP3 began).  That library sits on a shared drive on my Windows Home Server so it can be accessed through various streaming means (Home Server streams to iTunes software, XBOX, etc.).

Also in my home are roughly 6 computers ranging from desktop to laptops (mostly laptops).  These are used between my wife and myself (and one for the kids).

We all listen to music on our devices and via our machines.  We all want to listen to the same library, create our custom playlists and have them available everywhere.  We all want to be able to sync on whatever computer we want, but we’ll settle to be tied to one that you can pair with.

iTunes…sucks.

Yes, I’m looking at you iTunes.  I’m aware of the other options like Songbird, etc. but frankly I haven’t tried them out yet.  If you have and they will solve my woes, can you share your experiences?

Why does iTunes suck?  Easy…

  • It assumes 1 user/1 computer – the “library” is a local and static library unless the user interacts with it.  What I mean by this is it does not have the ability to monitor folders (like pretty much every other software out there for media does).  I want to point my iTunes library to my server share and whenever I add music to it via other computers, that other ‘libraries’ will be aware of it and just add it to my local library.
  • Portability sucks – try to transfer your iTunes library to another computer.  I dare you.  Navigate through all the Apple support suggestions and hacks online.  Frankly unless you are Mac to Mac migrating, it is not easy for a healthy configured library.
  • Not informative – one of my biggest issues is that when I configure the library to be a mapped drive (let’s say M:), if M: is not available for some reason, iTunes decides on it’s own without telling me that it is going to switch the library back to the local volume/hard drive.  Any future action (i.e., iTunes purchasing, Amazon purchasing, etc.) now doesn’t save to my server library.  WTF?!  Can you at least tell me: Hey user, that location you set for your library, ‘M:’ is not available right now…what would you like us to do.  Stop moving it around for me.
  • Home Sharing – what is this supposed to be again?  I thought this would save me.  I could have at least one place that would be the library and home share to other clients who could then use this feature to sync.  Um, nope.  This is basically the sharing they already had except with a new name.  Worthless.

I wish the iTunes team would put in their lab 3 iPods and 4 computers with 2 users and a library stored on the server.  Work toward making your software work in that environment as seamless as it does with 1 user and I’ll be happy.  Until then I have to navigate your changes and try my best to explain to my wife why the music we bough on the desktop is not on her laptop until she adds it to the library that is already mapped to the network share where the music already exists.  Yeah, that’s what I though.