Silverlight 2 - MSN Video ListBox

9 04 2008

NOTE TO RSS READERS: Click this link to see the images and source code correctly.

This is just one of those days: I have been redoing my Silverlight project for 5 times now and tried about 10 ways to do the same thing. All resulting in nothing. Not the result I wanted and not an error, If I had any hair I would have pulled it out. But I guess the choice to go work with a beta product was my own.

Onto the real reason of this blog post: to prevent you from having the same terrible day. I was able to reproduce the error in a test project which will also demonstrate some nice features of SL that do work as expected :).

The end result

Usually I don’t begin with the end, but I always like to visualize what I’m going to make:

image

and we will be using a the Random MSN Video service as our data source:
http://catalog.video.msn.com/randomVideo.aspx?mk=us&vs=0&df=99&c=10

For the lazy (most of us developers/designers), here is the source code we are going to create:

New Project

We start out by creating a new Silverlight Project in this demo I assumed it to be named SilverlightApplication2:

image

And in the next screen select "Add a new Web to the solution for hosting the control" and select "Web Application Project".

image 

After the 2 projects are created, set SilverlightApplication2TestPage.aspx as your start page.

XML to Objects for Databinding

Silverlight does not yet support the direct XML databinding available in WPF. So we will have to do our binding by hand. First let’s create the data model we will be using: Add a new class "VideoFeedItem.cs" to the SilverlightApplication2 project with the following code:

public class VideoFeedItem

{

    public string Title { get; set; }

    public string Source { get; set; }

    public string PublishDate { get; set; }

    public string Description { get; set; }

    public string ImageUrl { get; set; }

    public string VideoUrl { get; set; }

    public string ViewCount { get; set; }

}

Then add a new class "VideoDS.cs" to the SilverlightApplication2 project, I have added code comments to explain what it does:

/// <summary>

/// This class will load from a webservice and

/// provide a datasource which we can bind to from XAML.

/// </summary>

public class VideoDS : INotifyPropertyChanged

{

    // Webservice URI & Namespace

    private const string _randomVideo = "http://catalog.video.msn.com/randomVideo.aspx?mk=us&vs=0&df=99&c=10";

    readonly XNamespace _NS = "urn:schemas-microsoft-com:msnvideo:catalog";

 

    // Bindable Collection

    public ObservableCollection<VideoFeedItem> RandomVideos { get; set; }

 

    public VideoDS()

    {

        // Only load the video feed when we are in the browser (Not in blend/VS)

        if (HtmlPage.IsEnabled)

            LoadVideoFeed();

    }

 

    /// <summary>

    /// Load the video feed and put it into our collection

    /// </summary>

    private void LoadVideoFeed()

    {

        // Use a normal webclient to fetch the feed

        var wc = new WebClient();

        // New lambda style delegate declaration

        wc.DownloadStringCompleted += (sender, e) =>

        {

            var doc = XDocument.Parse(e.Result);

            // Linq Select from the XML Tree and create a new VideoFeedItem for each selected.

            var videos =

              from video in doc.Descendants(_NS + "video")

              select new VideoFeedItem()

              {

                Title = (string)video.Element(_NS+"title"),

                Source = (string)(video.Element(_NS + "source").Attribute("friendlyName")),

                PublishDate = DateTime.Parse((string)video.Element(_NS + "startDate")).ToShortDateString(),

                Description = (string)video.Element(_NS + "description"),

                ImageUrl = GetUriAsset(video.Element(_NS + "files"), "file", "2007"),

                VideoUrl = GetUriAsset(video.Element(_NS + "videoFiles"), "videoFile", "1002"),

                ViewCount = (string)video.Element(_NS + "usage").Element(_NS + "usageItem").Attribute("totalCount"),

              };

 

            // Add the results to the Collection

            RandomVideos = new ObservableCollection<VideoFeedItem>();

            foreach (var video in videos)

                RandomVideos.Add(video);

 

            // Notify all listeners that the data has changed

            PropertyChanged(this, new PropertyChangedEventArgs("RandomVideos"));

        };

        wc.DownloadStringAsync(new Uri(_randomVideo));

    }

 

    #region LINQ Uri Helper

    /// <summary>

    /// Helps with the finding of some data in the complicated XML Structure

    /// </summary>

    private string GetUriAsset(XContainer element, string nodeName, string formatCode)

    {

        var uris = from file in element.Descendants(_NS + nodeName)

                                   where (string)file.Attribute("formatCode") == formatCode

                                   select (string)file.Element(_NS + "uri");

        return ((uris.Count<string>() > 0) ? uris.First<string>() : string.Empty);

    }

    #endregion

 

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion

}

Binding

Now that we have setup the classes necessary for the data loading and binding, let’s add the ListBox to our page.xaml. Page.xaml should look like this:

<UserControl x:Class="SilverlightApplication2.Page"

   xmlns="http://schemas.microsoft.com/client/2007"

   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

   xmlns:d="http://schemas.microsoft.com/expression/blend/2008"             

   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"             

   xmlns:SilverlightApplication2="clr-namespace:SilverlightApplication2"

   mc:Ignorable="d"

   Width="600" Height="200">

    <UserControl.Resources>

        <SilverlightApplication2:VideoDS x:Key="VideoDS" d:IsDataSource="True"/>

    </UserControl.Resources>

    <Grid x:Name="LayoutRoot">

        <ListBox ItemsSource="{Binding RandomVideos, 
                                Source
={StaticResource VideoDS}}"/>

    </Grid>

</UserControl>

You can now run the application, it should look like this:

image

Template

As you see here, the listbox has found our collection, but has no clue whatsoever what to do with it. To tell it how it should display our data, we add ListBox.ItemTemplate and we change the orientation using the ListBox.ItemsPanel property:

<ListBox ItemsSource="{Binding RandomVideos, Source={StaticResource VideoDS}}">

    <ListBox.ItemTemplate>

        <DataTemplate>

            <TextBlock Text="{Binding Title}"/> 

        </DataTemplate>

    </ListBox.ItemTemplate>

    <ListBox.ItemsPanel>

        <ItemsPanelTemplate>

            <StackPanel Orientation="Horizontal"/>

        </ItemsPanelTemplate>

    </ListBox.ItemsPanel>

</ListBox>

This should result in the following (with other data ofcourse since the video’s are random):

image

I’m always a big fan of the separation of design and behavior, so let’s move the properties to a style. First remove the properties and add a Style to the ListBox:

<ListBox Style="{StaticResource ListBoxStyle}" ItemsSource="{Binding RandomVideos, Source={StaticResource VideoDS}}"/>

Style

And then add a Style to the UserControl:

<UserControl.Resources>

    <SilverlightApplication2:VideoDS x:Key="VideoDS" d:IsDataSource="True"/>

    <Style x:Key="ListBoxStyle" TargetType="ListBox">

        <Setter Property="ItemsPanel">

            <Setter.Value>

                <ItemsPanelTemplate>

                    <StackPanel Orientation="Horizontal"/>

                </ItemsPanelTemplate>

            </Setter.Value>

        </Setter>

        <Setter Property="ItemTemplate">

            <Setter.Value>

                <DataTemplate>

                    <TextBlock Text="{Binding Title}" />

                </DataTemplate>

            </Setter.Value>

        </Setter>

    </Style>

</UserControl.Resources>

The above style does exactly the same thing as out previous properties does, so no changes in result here. As a design choice you could also add the Style to the Resources in the App.xaml.

Image Binding

Next we’ll add an Image to the mix. We’ll also add a StackPanel and some Margin to make it look a little bit better.

<Setter Property="ItemTemplate">

    <Setter.Value>

        <DataTemplate>

            <StackPanel Width="200">

                <TextBlock Text="{Binding Title}" HorizontalAlignment="Center" Margin="5,5,5,0"/>

                <Image Height="120" Stretch="Uniform" Source="{Binding ImageUrl}" HorizontalAlignment="Center" Margin="10,10,10,10"/>

            </StackPanel>

        </DataTemplate>

    </Setter.Value>

</Setter>

Build and run the project, it should look something like this:

image

UserControl in a Style

To get a little bit more control over the video, we are going to move the content of the <DataTemplate> to a User Control. Add a new Silverlight UserControl to the project with the name : VideoFeedItemControl.

Move the XAML from the <DataTemplate> to the new usercontrol:

<UserControl x:Class="SilverlightApplication2.VideoFeedItemControl"

   xmlns="http://schemas.microsoft.com/client/2007"

   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Grid x:Name="LayoutRoot">

        <StackPanel Width="200">

            <TextBlock Text="{Binding Title}" HorizontalAlignment="Center" Margin="5,5,5,0"/>

            <Image Height="120" Stretch="Uniform" Source="{Binding ImageUrl}" HorizontalAlignment="Center" Margin="10,10,10,10"/>

        </StackPanel>

    </Grid>

</UserControl>

And place the <VideoFeedItemControl> in the Page.xaml <DataTemplate>:

<Setter Property="ItemTemplate">

    <Setter.Value>

        <DataTemplate>

            <SilverlightApplication2:VideoFeedItemControl/>

        </DataTemplate>

    </Setter.Value>

</Setter>

Ready to go, build and run. Let’s see our end result:
image
Hey, wait a minute!? that’s not what we were aiming for. That’s empty!

We did not get any errors, everything seems to be working correctly, what happened here?

The error

This was the point where it got frustrating. It took me more than a day to figure out. Remember the namespace handling in the page.xaml? One of these was a reference to our own project. This was generated automaticaly.

I’m talking about this line:

xmlns:SilverlightApplication2="clr-namespace:SilverlightApplication2"

Nothing wrong with it, right?

If you know what the problem is, the fix is very simple. Add:
assembly=SilverlightApplication2.

It should now be:

clr-namespace:SilverlightApplication2;assembly=SilverlightApplication2

We build and we get:

image

That looks more like it!

So we only needed an assembly reference to the current assembly? Strange behavior.

I’m still looking for the reason, but at least it is fixed. The strangest thing is that if you would move the UserControl back to the normal page. The UserControl works normally without the need of the assemblyname= in the namespace declaration.

So it seems this only happens when a UserControl is used within a template or style declaration.

Would be nice to have

Ofcourse it is much more work to have running video’s in the listbox. And there are at least 20 more things I can think of that could nicely extend the sample.

Maybe next time :)

Stay in the light!

Robertjan Tuit

Technorati tags: ,


Mix08

  • nederlands
1 02 2008

It has been some time ago that I have seen the inside of Windows Live Writer. I have been terribly busy with a project for the Silverlight Challenge en currently still am. This is why I haven’t blogged as much is I usually do. Also the previously promised report about the Envision-Event trip will have to wait.

Why this blog post then, U ask? I would like to share with you the joy of having registered for the Mix08 in Vegas. An event you should not miss this year.

With the release of  Silverlight 2.0 (beta) and subjects as IE8, ASP.NET MVC, IIS7, WPF 3.5, Dynamic Data Controls and.NET 3.5, I’m very much looking forward to it.

And the fact that it is in Las Vegas is not bad either. I haven’t settled yet on the flying schedule, and the hotel.

Who else is going? and if you are, how did you arrange your flight schedule and your hotel, any tips that can help me? The Venetian is a bit to pricey for my taste.

Going to dive back into my Silverlight 1.1 Alpha project. The longer I work with it the more I’m looking forward to the 2.0 beta release.

Hope to see you in Vegas!

Robertjan Tuit



.NET Source Code Released

  • nederlands
17 01 2008

Microsoft released the .NET source code today, available from withing Visual Studio 2008.

Many of us have been longing for this moment, and many others have pointed out that it is very unwise to use it in the light of patents and copyright.

Especially that copyright discussion has kept us busy for a while but i’m convinced that here in Europe we have nothing to fear. You should keep in mind that if you have plans on brining your software to the states it is a whole other ballgame.

Check the following links for more information:

  • The blog post from Scott Guthry
  • How to setup browsing from visual studio 2008
  • Phil Haacked : Perception vs Reality on the patents
  • Don’t look at the sourcecode of .NET licensed under the ‘Reference license’

    Robertjan Tuit



  • Working together with Visual Studio 2005 and 2008

    • nederlands
    4 01 2008

    With Visual Studio 2008 you have the ability to keep working with 2.0 projects. And when everyone in your team works with 2008 this works perfectly.

    But when a few keep working with 2005 you have to solve a few little problems.

    .sln files
    Visual Studio 2008 converts a solution file to a new format, after which 2005 is not able to open it any more.

    When you check the actual changes made to the solution file, in 95% percent of the cases it is only in the header.

    It changes "Format Version 9.00" in "Format Version 10.00" and "# Visual Studio 2005" in "# Visual Studio 2008".

    If you change these values back Visual Studio will eat the files again.

    .csproj files
    Project fikles are not converted. But when you create them in 2008 and try to open them in 2005 there are some things you need to check.

    For example the new variable $(MSBuildToPath) used by 2008 is unknown in 2005, the exact same $(MSBuildToPath) works in 2005 and 2008. You can just change the project file and it will work again.

    The Solution
    These little changes can be done by hand, but ofcourse it can also be done automagicly.

    To make this work you need to create 2 solution files, one for 2005 and one for 2008. When you maken changes in the 2005 file, you just let Visual Studio open the file and save it as the 2008 file. For the other way around you use a batch file and a SearchAndReplace application to copy the file and make the changes to the solution file.

    You can download my own very simple implentation here



    ASP.NET 3.5 Extensions

    10 12 2007

    Het lange wachten is over, we kunnen eindelijk aan de slag met het MVC Framework. Gebundeld met de onderdelen die tot nu toe in de asp.net futures release zaten heeft het asp.net team vandaag een preview van MVC framework uitgebracht in de ASP.NET 3.5 Extensions. Je kunt ze “gewoon” naast de huidige assemblies blijven draaien, dus ASP.NET MVC Object Viewerinstalleren en spelen maar!

    De extensions download bevat:

    Je krijgt er dus gratis en voor niets ook nog is het Entity Framework bij, ik kan niet wachten tot ik er vanavond lekker mee kan gaan spelen!

    Direct downloaden :

    En nog een klein overzichtje van wat informatieve blog posts, walktroughs en screencasts:

    Veel plezier!

    Robertjan Tuit

    Bronnen: ScottGu, Nikhilk & Phil HAACKED.



    Visual Studio 2008 & Silverlight 1.1 Alpha

    27 11 2007

    Binnen 2 weken betekend dus kennelijk bij Microsoft: 1 week want dat is de tijd die er overheen gegaan is sinds de release van Visual Studio 2008. Dus snel downloaden die Visual Studio 2008 want nu kan je er ook met Silverlight 1.1 mee aan de slag.

    Links :

    Bron : Scott Guthry

    Robertjan Tuit



    Released : Visual Studio 2008, .NET 3.5 & Ajax Control Tookit

    20 11 2007

    Ik in ieder geval, en ik denk een aardig aantal mensen met mij, zit al een tijdje op dit nieuws te wachten. En vandaag is het zover , de RTM van Visual Studio 2008, Team Foundation Server 2008 en .NET 3.5.

    Te downloaden via :

    Let wel op: de Silverlight 1.1 Alpha en Web Deployment Add-Ins werken NOG NIET met deze release, deze hopen ze de komende weken beschikbaar te maken.

    Een korte feature list van VS2008 :

    VS2008 is ontwikkeld met TFS. Channel 9 heeft een video met Somasager over dit onderwerp : Channel9 VS 2008 Built with TFS Talk 

    Daarnaast heeft het Ajax Control Tookit team besloten om hun nieuwe release ook samen te laten hangen met de Visual Studio 2008 Release. Die kun je hier vinden : Nieuwe Ajax Control Tookit Release (11119 release)

    Bron : De enige echte Scott Guthry natuurlijk, en Somasegar voor de TFS video.

    Robertjan Tuit



    VS2008 Beta 2 VPC verloopt 1 November

    31 10 2007

    Mocht je visual studio 2008 als VPC hebben gedownload, en als je met silverlight bezig bent geweest dan kun je bijna niet anders) dan heb je per 1 November een probleem: Het operating system van die specifieke virtual pc zal verlopen (de standalone versie heeft hier geen last van).

    Dus zorg dat je al je persoonlijke gegevens veilig hebt gesteld, een vpc zonder timeout kan je hier downloaden. En waarschuw even iedereen in je omgeving, dit kan zomaar een behoorlijk verlies van gegevens betekenen als je even niet oplet!.

    Bron : ScottGu

    Robertjan Tuit



    MSDN Nuggets & Silverlight Debugging op de Mac

    5 09 2007

    Wat kan je toch makkelijk verblijdt worden door nieuwe sources van informatie. Ik kan er echt niet genoeg van krijgen, en hoe meer mensen informatie gaan delen hoe groter de kennis word. Een van de dingen die ik vandaag tegen kwam was MSDN Nuggets. Hier staan korte video’s over  een heleboel onderwerpen, van LINQ tot Office Open XML en van Visualstudio tot Silverlight, zeker de moeite waard om even te bekijken.

    Tussen deze silverlight nuggets kwam ik dit mooie voorbeeld tegen :

    Silverlight - Debugging between Mac and Windows

    Ik had het zelf niet beter kunnen uitleggen ;)

    Robertjan Tuit



    ClearType Consolas, ruimte en rust in Visual Studio

    13 08 2007

    ConsolasNa alle negatieve geluiden over Vista is de stap om over te gaan op Vista niet erg veel kleiner geworden dan hij al was. Toch heb ik een paar weken geleden op een nieuwe laptop de grote stap gewaagd. Ik moet zeggen het is inderdaad niet al te stabiel en erg blij ben ik er niet mee, er is 1 punt waarop Vista vele male beter is.

    Het wordt standaard geinstalleerd bij Vista en standaard ingesteld in Visual Studio, je hebt het eigenlijk niet eens door totdat je weer teruggaat naar je “oude” xp machine. Het is een echte aanrader voor iedereen die langer dan een uur per dag kijkt naar het visual studio scherm. Het betreft hier een font speciaal ontwikkeld voor ons ontwikkelaars : Consolas, en laat deze nou ook los te downloaden zijn!

    Let wel op, het font is speciaal ontwikkeld voor ClearType, dus alleen voor eigenaren van platte schermen (bestaat er nog iets anders dan?) die in XP cleartype aan hebben staan, wat zeker aan te raden is.

    Consolas kan je hier downloaden :
    http://www.microsoft.com/downloads/details.aspx?familyid=22e69ae4-7e40-4807-8a86-b3d36fab68d3&displaylang=en

    En cleartype zet je aan door te gaan naar : Display Properties –> Appearance –> Effects –> 2e dropdown op ClearType zetten.

    Veel plezier met je nieuw gevonden ruimte en rust.

    Robertjan Tuit