Click here to Skip to main content
15,867,686 members
Articles / Desktop Programming / XAML

Silverlight 4: Creating an Application to Play Offline Media

Rate me:
Please Sign up or sign in to vote.
4.92/5 (14 votes)
11 Mar 2010CPOL2 min read 34.2K   769   18   5
Discovering the features of Silverlight 4

Introduction

Silverlight 4 has some huge advances in the RIA world, like the possibility of communication with COM components (Office, Windows Media Player, etc.), the possibility of getting data from the Webcam and microphone, and for the scenario for this solution to access the user's folders and consume data from it.

I would like to give special thanks for the developer team at Truetech, my new home, and for the friends that have helped me in achieving this accomplishment.

Where to Start

For this project, you will need the Visual Studio 2010 Beta 2 (the Release Candidate does not support Silverlight 4 at the current moment) and the Silverlight tools for Visual Studio 2010 or Expression Blend Preview for .NET 4.

First Off

After the installation of these tools, you should open the Visual Studio 2010 and create a new Silverlight Project.

CreateProject.JPG

After this, a popup window will show up:

NewSilverlight.JPG

Just click OK and you are good to go.

Configuring the Out of the Browser Experience

Once you have done the initial configurations of the application, you must set the information for the Out of the browser experience, which is necessary for our scenario, this is achievable by right clicking the Silverlight project and selecting "Properties":

Properties.JPG

The follow tab will show in VS, set the configuration to match the image below:

SetProperties.JPG

Then click the out-of-browser settings button and mark the "Required elevated trust when running outside the browser" like in the image below:

Elevate.JPG

And Now the Code

We have an interface called IShell, this interface is implemented by the MainPage like:

C#
public partial class MainPage : UserControl, IShell
{
    public MainPage()
    {
        InitializeComponent();
        this.Loaded += new RoutedEventHandler(MainPage_Loaded);
    }

    void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        ResetVisual(false);
    }

    public void ResetVisual(bool justInstalled)
    {
        if (App.Current.InstallState == InstallState.Installed)
        {
            if (App.Current.IsRunningOutOfBrowser)
                this.LayoutRoot.Content = new MainAppView();
            else
            {
                if (justInstalled)
                    this.LayoutRoot.Content = new InstallationCompletedView();
                else
                    this.LayoutRoot.Content = new RunningOnTheBrowserView();
            }
        }
        else
        {
            var view = new ApplicationNotInstalledView();
            view.Shell = this;
            this.LayoutRoot.Content = view;
        }
    }
}

Then we have another interface called IView, which is implemented by the ApplicationNotInstalledView:

C#
public partial class ApplicationNotInstalledView : UserControl, IView
{
    public static readonly DependencyProperty ShellProperty = DependencyProperty.Register(
        "Shell", typeof(IShell), typeof(ApplicationNotInstalledView),
        new PropertyMetadata(
            (sender, e) =>
            {

            }));

    public IShell Shell
    {
        get { return GetValue(ShellProperty) as IShell; }
        set { SetValue(ShellProperty, value); }
    }

    public ApplicationNotInstalledView()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        App.Current.Install();
        App.Current.InstallStateChanged += 
		new EventHandler(Current_InstallStateChanged);
    }

    void Current_InstallStateChanged(object sender, EventArgs e)
    {
        if (App.Current.InstallState == InstallState.Installed)
            Shell.ResetVisual(true);
        App.Current.InstallStateChanged -= Current_InstallStateChanged;
    }
}

As you can see, the ApplicationNotInstalledView wires up the App.Current.InstallStateChanged event, to perform an action when the installation has been finished. We have also some informational views, which are there only to notify the user about the state of the application (no code at all).

Main Application View

In the MainAppView class, which is our real application, we have the following code on the Open button click event:

C#
private void Button_Click(object sender, RoutedEventArgs e)
{
    var ofd = new OpenFileDialog();
    ofd.Filter = "Media Files |*.wmv;*.wma;*.mp3";
    ofd.Multiselect = false;
    if((bool)ofd.ShowDialog())
    {
        if(File.Exists(ofd.File.FullName))
        {
            LoadMedia(ofd.File.OpenRead());
        }
    }
}

The concept of Silverlight 4 is that running on the sandbox (Out-of-Browser) the application can, if the correct permissions are set (this is why we need to elevate the application), open the special folders of a user, such as "My Documents", "My Music", "My Videos", and get the data stored inside these folders, but if you try to access a file outside this scope it simply ignores it, so no exception is thrown too.

Points of Concern

In the current version of Silverlight 4, we cannot access a file on the MediaElement by its Uri if the Uri is local (File scoped Uri is not supported by MediaElement on Silverlight). So to bypass this limitation, you can open a Stream of the File and then set the Stream of the MediaElement by using the SetSource method, like this:

C#
void LoadMedia(Stream file)
{
    player.SetSource(file);
}

History

  • 11th March, 2010: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
Brazil Brazil
Senior Software Architect from Brazil.

Comments and Discussions

 
GeneralVery good Pin
wellingtonp13-Mar-10 9:32
wellingtonp13-Mar-10 9:32 
Good article
GeneralNice Pin
Marcelo Ricardo de Oliveira11-Mar-10 6:46
mvaMarcelo Ricardo de Oliveira11-Mar-10 6:46 
GeneralRe: Nice Pin
Raul Mainardi Neto11-Mar-10 7:37
Raul Mainardi Neto11-Mar-10 7:37 
GeneralHello there Pin
Sacha Barber11-Mar-10 5:57
Sacha Barber11-Mar-10 5:57 
GeneralRe: Hello there Pin
Raul Mainardi Neto11-Mar-10 6:03
Raul Mainardi Neto11-Mar-10 6:03 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.