Click here to Skip to main content
Click here to Skip to main content

Silverlight 4 Video Player

By , 8 May 2011
 

NOTE: This article is outdated due to changes in the latest version of RX Extensions.

Introduction

This project demonstrates an implementation of the View Model Style pattern to create a fully "designable" Silverlight video player. This is not to be confused with a "skinable" video player. A skinable video player allows you to change the look and feel of the buttons that control the player. A designable player allows a designer to use any set of controls to implement the video player.

The View Model Style pattern allows a programmer to create an application that has absolutely no UI. The programmer only creates a ViewModel and a Model. A designer with no programming ability at all is then able to start with a blank page and completely create the View (UI) in Microsoft Expression Blend 4 (or higher).

Note: to build the project, you may need to install the Silverlight RX Extensions from http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx.

The Power of View Model Style

This Silverlight project is not a full featured video player, but it actually works, and hopefully demonstrates a non-trivial example of a View Model Style Silverlight project. Certain functions such as the pause button, full screen support, and skip ahead were left out to simplify the example code as much as possible.

If you are new to View Model Style, it is suggested that you read Silverlight View Model Style: An (Overly) Simplified Explanation for an introduction.

View Model Style

image

Much has been written about the View Model Style pattern, and there are various interpretations. In this example, we will implement the pattern with as little code as possible. We will try to present it in the easiest possible way. The Model and the View of the View Model Style are very simple. The Model contains Web Services, and the View is the UI (that is created in Expression Blend with no coding). The only complex part is the ViewModel. In the ViewModel, all functionality will be implemented using:

  1. Properties - One of something. This could be a String or an Object. Implements INotifyPropertyChanged so that any element bound to it is automatically notified whenever it changes.
  2. Collections - A collection of something. This is of type ObservableCollection so that any element bound to it is automatically notified whenever it changes.
  3. Commands - An event that can be raised. Also, one parameter of type Object can be passed. This implements ICommand.

For the commands, we will only need to use the InvokeCommandAction behavior.

That's it. This is the "simplified" View Model Style.

A Silverlight View Model Style Video Player

Let's first start with the experience a designer would have in using the View Model Style pattern to completely redesign the video player.

When you download the attached code, you will need to place some .wmv videos in the Video folder.

When you run the project, the Web Service in the web project will detect what videos are in the folder and pass them to the Silverlight application.

  • The list of videos will show in the combo box dropdown.
  • You can select a video from the combo box and then click the Play button to play the video.
  • A progress bar will show the current progress.
  • The exact location of the video will display above the video.
  • The current and total time of the video will also display.
  • The Stop button will stop the video.

When you open the project in Expression Blend and open the MainView.xaml file, click on the Data tab...

You will see that there is a Data Context section. The Data Context is set to the ViewModel, and displays all the Properties, Collections, and Commands that the UI can interact with. The designer only needs to interact with these elements to implement their own video player.

The image above shows what is bound to what. However, note that while buttons are bound to, and raise ICommands, practically anything can raise an ICommand, it does not have to be a button. In the tutorial TreeView SelectedItemChanged Using View Model Style, a TreeView control is used to raise the ICommand.

Redesign the Video Player

We can delete the existing MainPage.xaml file...

... and create a new one.

If we click on LayoutRoot in the Objects and Timeline window...

... and click on the New button next to DataContext...

... and select MainViewModel and click OK:

When we click on the Data tab...

... we will see the Data Context has been set for the page.

Let me repeat this important point: We will not need to create a single line of code to implement the video player.

Create the UI

The one control that is required is the MediaElement. In Expression Blend:

  1. Click the Asset button
  2. Locate the MediaElement
  3. Drag it to the design surface

Make sure you set the AutoPlay to false by un-checking the box in the Properties for the MediaElement.

I went to the Alan Beasley article: http://www.codeproject.com/KB/expression/ArcadeButton.aspx and stole a button (he really does good work; when you click on the button, it actually animates and behaves like a real button).

I then created the "Masterpiece" you see above. Of course, anyone could do better. I just wanted to show how radically different the UI could be, yet still work without any code changes.

Wire-up the MediaElement - Learn to "Think View Model Style"

The UI is created, all we need to do is bind the UI elements to the ViewModel and the application is complete.

To understand how we bind the UI elements to the ViewModel, we need to learn a few things to "Think Like View Model Style". Basically, we:

  • Bind UI elements to Properties or Collections, and when the ViewModel puts something in those Properties or Collections, events will automatically be raised on the bound UI elements.
  • We can use the InvokeCommand behavior to respond to particular events and raise other events in the ViewModel.

In this application, we need to wire-up the MediaElement to the ViewModel. To do this, we have to:

  1. Bind the MediaElement to the SelectedVideoProperty (URI). This will cause the MediaElement to always play the video that the ViewModel sets to that property.
  2. Use an InvokeCommand behavior to raise the MediaOpenedCommand (ICommand). This behavior is configured to fire when the MediOpened event is raised on the MediaElement (this happens automatically when the MediaElement is ready to play the video). The behavior also passes a reference to the MediaElement as a parameter to the ViewModel (the ViewModel will use this reference to the MediaElement when other commands such as Start and Stop are called).

Let's walk through these steps:

In the Objects and Timeline window, select the MediaElement.

In the properties for the MediaElement, select the Advanced options for Source.

Select Data Binding...

Set it to SelectedVideoProperty and click OK.

You will know an element is bound because it will have a gold box around it.

In Assets, click and drag an InvokeCommand behavior...

... and drop it under the MediaElement in the Objects and Timeline window.

In the properties for the behavior, set MediaOpened for the EventName and click the Data bind button next to Command.

Select MediaOpenedCommand and click OK.

Select Advanced options for CommandParameter:

Select Data Binding...

Click the Element Property tab, and select MediaElement, and click OK.

That was the hard part. The rest is just binding the remaining Properties, Collections, and Commands.

Binding Properties and Collections

These are the remaining Properties and Collections that need to be bound.

For example, the ProgressBar control has its Value and Maximum properties set to CurrentPositionProperty and TotalDurationProperty, respectively.

The ListBox control is naturally bound to SilverlightVideoList, but the SelectedIndex for the ListBox is also bound to SelectedVideoInListProperty. The reason for this is that you cannot set the Selectedindex until after the list has been loaded.

The ViewModel fills the SilverlightVideoList, and only after it has filled that collection does it check to see if there are any items, and if there are, sets the Selectedindex value.

Binding Commands

These are the remaining Commands that need to be bound. To bind them, simply drop an InvokeCommand behavior on the control and set the properties to the respective commands.

For example, the ListBox uses an InvokeCommand behavior to call the SetVideoCommand when its SelectionChanged event is raised.

Its CommandParameter is bound to the SelectedItem of the ListBox.

That's about it. If you're a designer, you can skip the next section.

The Code

The website part of the code is simply a website with a Web Service that returns a list of any video that is in the Videos folder.

The Silverlight project consists of only a few files. The files that are important at this point are:

  • DelegateCommand.cs - A helper file that allows us to easily create ICommands (see: Silverlight View Model Style File Manager for a full explanation of this file).
  • SilverlightVideos.cs - This is the Model. It consists of a single Web Service method.
  • MainViewModel.cs - This is the ViewModel. This is where all the "magic" happens.

The Model

The Model for this application consists of a single web method in the SilverlightVideos.cs file. The "twist" is that we are using RX Extensions that call the Web Service and return an IObservable.

public static IObservable<IEvent<GetVideosCompletedEventArgs>> GetVideos()
{
  // Uses http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx
  // Also see: http://programmerpayback.com/2010/03/11/
  //           use-silverlight-reactive-extensions-rx-to-build-responsive-uis/
  // Also see: http://www.silverlightshow.net/items/
  //           Using-Reactive-Extensions-in-Silverlight-part-2-Web-Services.aspx 

  // Set up web service call
  WebServiceSoapClient objWebServiceSoapClient =
    new WebServiceSoapClient();

  // Get the base address of the website that launched the Silverlight Application
  EndpointAddress MyEndpointAddress = new
    EndpointAddress(GetBaseAddress());

  // Set that address
  objWebServiceSoapClient.Endpoint.Address = MyEndpointAddress;

  // Set up a Rx Observable that can be consumed by the ViewModel
  IObservable<IEvent<GetVideosCompletedEventArgs>> observable = 
    Observable.FromEvent<GetVideosCompletedEventArgs>(
    objWebServiceSoapClient, "GetVideosCompleted");
  objWebServiceSoapClient.GetVideosAsync();

  return observable;
}

The ViewModel

image

The ViewModel is where all the Properties, Collections, and Commands are created.

This is the constructor of the ViewModel:

public MainViewModel()
{
    // Set the command property
    MediaOpenedCommand = new DelegateCommand(MediaOpened, CanMediaOpened);
    PlayVideoCommand = new DelegateCommand(PlayVideo, CanPlayVideo);
    StopVideoCommand = new DelegateCommand(StopVideo, CanStopVideo);
    SetVideoCommand = new DelegateCommand(SetVideo, CanSetVideo);
    
    // Call the Model to get the collection of Videos
    GetListOfVideos();
}

It sets up the Commands by using the DeleagateCommand method (from the DelegateCommand.cs file) to create ICommands. Next, it calls the GetListOfVideos() method.

private void GetListOfVideos()
{
    // Call the Model to get the collection of Videos
    SilverlightVideos.GetVideos().Subscribe(p =>
    {
        if (p.EventArgs.Error == null)
        {
            // loop thru each item
            foreach (string Video in p.EventArgs.Result)
            {
                // Add to the SilverlightVideoList collection
                SilverlightVideoList.Add(Video);
            }

            // if we have any videos, set the selected item value to the first one
            if (SilverlightVideoList.Count > 0)
            {
                SelectedVideoInListProperty = 0;
            }
        }
    });
}

This method calls the GetVideos() method in the Model that fills the SilverlightVideoList collection. It also sets the SelectedVideoInListProperty property if there are videos in the collection.

The SilverlightVideoList collection is a simple ObservableCollection:

private ObservableCollection<string> _SilverlightVideoList = 
        new ObservableCollection<string>();
public ObservableCollection<string> SilverlightVideoList
{
    get { return _SilverlightVideoList; }
    private set
    {
        if (SilverlightVideoList == value)
        {
            return;
        }

        _SilverlightVideoList = value;
        this.NotifyPropertyChanged("SilverlightVideoList");
    }
}

When the SelectedVideoInListProperty property is set, the UI control that is bound to it (the listbox or the combo drop down box) should raise the SetVideoCommand command that sets the SelectedVideoProperty:

public ICommand SetVideoCommand { get; set; }
public void SetVideo(object param)
{
    // Set Video
    string tmpSelectedVideo = string.Format(@"{0}/{1}", 
                              GetBaseAddress(), (String)param);
    SelectedVideoProperty = new Uri(tmpSelectedVideo, 
                                    UriKind.RelativeOrAbsolute);

    // Stop Progress Timer
    progressTimer.Stop();
}

private bool CanSetVideo(object param)
{
    // only set video if the parameter is not null
    return (param != null);
}

The MediaElement is bound to the SelectedVideoProperty, and will automatically start loading the video. When it has opened the video, it will call the MediaOpenedCommand command that will:

  • Pass an instance of the MediaElement as a parameter so it can be stored in a private variable in the ViewModel (this will be used when the Start and Stop commands are raised).
  • Starts a DispatcherTimer that will fire each second and check the current position of the MediaElement (in the private variable) and update the CurrentPostionProperty.
public ICommand MediaOpenedCommand { get; set; }
public void MediaOpened(object param)
{
    // Play Video
    MediaElement parmMediaElement = (MediaElement)param;
    MyMediaElement = parmMediaElement;

    this.progressTimer = new DispatcherTimer();
    this.progressTimer.Interval = TimeSpan.FromSeconds(1);
    this.progressTimer.Tick += new EventHandler(this.ProgressTimer_Tick);

    SetCurrentPosition();
}

private bool CanMediaOpened(object param)
{
    return true;
}

The code for the Start and Stop Commands is:

#region PlayVideoCommand
public ICommand PlayVideoCommand { get; set; }
public void PlayVideo(object param)
{
    // Play Video
    MyMediaElement.Play();
    progressTimer.Start();
}

private bool CanPlayVideo(object param)
{
    bool CanPlay = false;
    // only allow Video to Play if it is not already Playing
    if (MyMediaElement != null)
    {
        if (MyMediaElement.CurrentState != MediaElementState.Playing)
        {
            CanPlay = true;
        }
    }
    return CanPlay;
}  
#endregion

#region StopVideoCommand
public ICommand StopVideoCommand { get; set; }
public void StopVideo(object param)
{
    // Stop Video
    MyMediaElement.Stop();
    progressTimer.Stop();
}

private bool CanStopVideo(object param)
{
    bool CanStop = false;
    // only allow Video to Stop if it is Playing
    if (MyMediaElement != null)
    {
        if (MyMediaElement.CurrentState == MediaElementState.Playing)
        {
            CanStop = true;
        }
    }
    return CanStop;
}  
#endregion

The SetCurrentPosition() method sets CurrentProgressProperty, CurrentPositionProperty, and TotalDurationProperty:

private void SetCurrentPosition()
{
    // Update the time text e.g. 01:50 / 03:30
    CurrentProgressProperty = string.Format(
        "{0}:{1} / {2}:{3}",
        Math.Floor(MyMediaElement.Position.TotalMinutes).ToString("00"),
        MyMediaElement.Position.Seconds.ToString("00"),
        Math.Floor(MyMediaElement.NaturalDuration.TimeSpan.TotalMinutes).ToString("00"),
        MyMediaElement.NaturalDuration.TimeSpan.Seconds.ToString("00"));

    CurrentPositionProperty = MyMediaElement.Position.TotalSeconds;
    TotalDurationProperty = MyMediaElement.NaturalDuration.TimeSpan.TotalSeconds;
}

Wrap Your Head Around View Model Style

It takes a bit of practice to wrap your head around View Model Style. However, it is not hard, and you will find you will use less code than you would normally use. The main thing you want to get used to is binding everything. If you find yourself needing to raise an event from the UI and you are stuck, you are usually not binding enough things. Let a change in a value in the ViewModel raise the event for you through bindings.

How Can You Learn More About Expression Blend?

To learn how to use Expression Blend, all you have to do is go to: http://www.microsoft.com/design/toolbox/. This site will give you the free training you need to master Expression Blend. It will also cover the design principles to make you a better designer.

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)

About the Author

defwebserver
Software Developer (Senior) http://ADefWebserver.com
United States United States
Member
Michael Washington is a Microsoft Silverlight MVP. He is a Silverlight developer and an ASP.NET, C#, and Visual Basic programmer.
 
He is a DotNetNuke Core member and has been involved with DotNetNuke for over 4 years. He is the Co-Author of Building Websites with DotNetNuke (4 and 5).
 
He is one of the founding members of The Open Light Group (http://openlightgroup.net).
 
He is the founder of http://LightSwitchHelpWebsite.com
 
He has a son, Zachary and resides in Los Angeles with his wife Valerie.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5memberChristian Amado28 Jul '12 - 5:13 
Good explanation here! 1
QuestionFix for Silverlight Version 1.0.10621.0 [modified]memberMember 456543326 Sep '11 - 2:41 
Silverlight Version 1.0.10621.0 of RX dll
 
This a test example of my WebService
I pass in a UserId as an int (from my ViewModel or where ever you want), and get back a User object which is defined in the ASP.NET.MVC hosting application.
 
In my .SVC file I have a method
 
public User GetUsers(int id)
 

Here's my Silverlight WCF wrapper
 
public class ReactiveExtensionsForIUserService : IReactiveExtensionsForIUserService
{
 
private readonly IUserService _client;
 
public ReactiveExtensionsForIUserService()
{
var endAddr = new System.ServiceModel.EndpointAddress("http://localhost:16454/UserService.svc");
_client = new UserServiceClient("BasicHttpBinding_IUserService", endAddr);
}
 
public IObservable GetUsersAsObservable( System.Int32 id)
{
return Observable
.Start(()=> Observable.FromAsyncPattern(_client.BeginGetUsers, _client.EndGetUsers)(id))
.SelectMany(p=>p);
}

}
}
 

//------------------------------------- Interface definition -----------------------------------------


public interface IReactiveExtensionsForIUserService
{
IObservable GetUsersAsObservable(System.Int32 id) ;

}
 

In my ViewModel I have the following
 
private string _userName;
public string UserName
{
get { return _userName; }
 
set
{
_userName = value;
NotifyPropertyChanged(m => m.UserName);
 
}
}
 
Here’s the call to the Web Service, the 'result' is the User object in this example. My User object has a public get/setter property named FirstName
 
var client = new ReactiveExtensionsForIUserService>();
var observable = client.GetUsersAsObservable(1);
observable.Subscribe(
result => UserName = result.FirstName,
error => Console.WriteLine("Error"),
() => Console.WriteLine("Completed")
);
 

You may have to NotifyPropertyChanged on the UI thread as the Observer will not be on the UI Thread, so here’s an INPC I use
 
protected void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
// Always fire the event on the UI thread
if (Deployment.Current.Dispatcher.CheckAccess())
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
else
{
Deployment.Current.Dispatcher.BeginInvoke(() => PropertyChanged(this, new PropertyChangedEventArgs(propertyName)));
}
}
}
 

I suggest you create a very small test project to get this working first, rather than trying to get this working in this video project
 
In my project I do it diffrent to what I’ve posted here as I use Unity DI for newing up object instance etc. But the end result is just the same
 
Hope this helps

modified 26 Sep '11 - 8:55.

AnswerRe: Fix for Silverlight Version 1.0.10621.0mvpdefwebserver26 Sep '11 - 3:26 
Thank You!
GeneralRe: Fix for Silverlight Version 1.0.10621.0memberMember 456543326 Sep '11 - 3:36 
Your welcome
It'd be so nice if MS kept their RX documentation up to date with their RX releases !
GeneralDoes not work with new Rx Extensions dropmemberPaul Scholz8 May '11 - 7:54 
In SilverlightVideos.cs, this line now breaks:
 
// Set up a Rx Observable that can be consumed by the ViewModel
IObservable> observable =
Observable.FromEvent(objWebServiceSoapClient, "GetVideosCompleted");
 
The latest Rx Extentions drop (v1.0.10425) has broken Observable.FromEvent and various postings on the net recommend changing to the FromEventPattern method. Trying to use the old Rx Extensions leads to namespace conflicts, because System.Observable methods are now defined in System.Reactive.Linq.
 
I'm pretty new to this and still trying to figure it all out, so I don't have an answer yet, but I thought I'd let you know you need to update your code to the latest stuff because someone starting from scratch will find it broken.
GeneralRe: Does not work with new Rx Extensions dropmvpdefwebserver8 May '11 - 8:45 
(sigh) thats what happens when I use beta components. I will add to the top of the article, that this is outdated due to changes in the latest version of RX Extensions.
GeneralRe: Does not work with new Rx Extensions dropmemberPaul Scholz8 May '11 - 9:08 
So, I've temporarily solved this by going into Solution Explorer and deleting the reference to System.Reactive from the new framework and by adding a reference to the old System.Reactive that comes in the downloaded project.
 
This will let me get your project up and running while you update the parts that rely on the Reactive framework. I think you can still use Observable.FromEvent, you just have to change your arguments to fit the new signature using Action.
GeneralRe: Does not work with new Rx Extensions dropmvpdefwebserver8 May '11 - 9:22 
I have this version that does the same thing but does not use Rx Extensions:
Dynamically Loading Silverlight Video Players using MEF[^]
GeneralRe: Does not work with new Rx Extensions dropmemberPaul Scholz8 May '11 - 9:41 
That looks cool as well and I'll be looking at that player too. Just a quick note, I got the player in this article up and running just by using the older Reactive framework that comes with your project, but you should know that the Silverlight player does not work with .wmv files created by the older PhotoStory authoring product. I guess the player doesn't support that codec. Once I removed those files from my Video directory, everything worked fine.
 
Good job! I look forward to the new code update using the new Reactive framework, which appears to be Release Candidate 0 at the time of this writing.
GeneralRe: Does not work with new Rx Extensions dropmvpdefwebserver8 May '11 - 9:51 
Sorry for the trouble this one caused you. However, I don't think I will update to the latest Rx Extensions even when they come out, because I no longer feel that Rx Extensions are the way to go. Yes they work, but they are too darn confusing for most people. The method I use in the other articles is easier to understand.
GeneralRe: Does not work with new Rx Extensions dropmemberMember 456543326 Sep '11 - 2:46 
Hi
 
I've posted an example of using the newer RX dll
GeneralCan't get this to workmemberdprentis6 May '11 - 3:26 
Seems like a great demo, but I can't get it to work. Installed Rx for SL 4 and added a wmv file in the video directory.
 
Running the demo and then selecting the video file throws a null exception at progressTimer.Stop() in SetVideo. This is because MediaOpened (which initializes progressTimer) has not been triggered.
 
I can resolve the null exception by moving the progressTimer initialization into the MainViewModel constructor, but the video still doesn't play back because MediaOpened is never triggered.
 
I am wondering why this is happening- could my video file be invalid/incompatable or is something else wrong? The file plays pack ok in media player and resides at the url shown on the player page.
GeneralRe: Can't get this to workmvpdefwebserver6 May '11 - 3:30 
I am stummped. Can you try the code in this version: Dynamically Loading Silverlight Video Players using MEF[^]
GeneralMy vote of 5memberaofeng316 Apr '11 - 22:49 
thanks very good
GeneralMy vote of 5.membermbcrump5 Feb '11 - 13:40 
Great article, I am actually doing something like this right now for a hobby project.
GeneralRe: My vote of 5.mvpdefwebserver5 Feb '11 - 14:08 
Thanks for the vote! I enjoy your articles also.
QuestionCan it does Live streaming from multicast IP or UDP protocol ?memberRajan UNCC20 Apr '10 - 5:29 
I really liked this article and i was wondering that if it is possible to do live streaming using this silverlight 4.0 player I need to stream a live video from udp://224.168.111.222:2345 is it possible with silverlight if i pass this url as a source and it start streaming (video format is mpeg4). if anybody knows any possible way to do this please let me know i will really appriciate that.
GeneralMy vote of 1memberVickyC#12 Apr '10 - 5:38 
does not work
GeneralRe: My vote of 1memberAlan Beasley12 Apr '10 - 8:04 
Hi Vicky,
 
How about a bit more info on why?
 
Please appreciate its hard to consider every option, or possible error first time....
 
So hold off on the verdict until researched...
 
Alan
GeneralRe: My vote of 1memberdefwebserver12 Apr '10 - 8:24 
VickyC# wrote:
does not work

 
I am so sorry about this. I just added to the text that you need to download and install the Silverlight 3 RX extensions to build the project.
 
The reason I did not include them is that Microsoft announced that RX will be part of Silverlight 4 that is suppose to be released on 4/13/2010.
GeneralRe: My vote of 1memberDewey12 Apr '10 - 12:31 
Well, I wouldn't give this a 1(I think it deserves a 5), but I too am not able to compile this. I get the following error(s).
 
Error 1 'IObservable' is an ambiguous reference between 'System.IObservable<System.Collections.Generic.IEvent<MVVMVideoPlayer_Test.wsVideos.GetVideosCompletedEventArgs>>' and 'System.Collections.Generic.IObservable<System.Collections.Generic.IEvent<MVVMVideoPlayer_Test.wsVideos.GetVideosCompletedEventArgs>>' C:\Documents and Settings\Administrator\Desktop\Silverlight 4 Code\MvvmVideo\MVVMVideoPlayer_Test\Model\SilverlightVideos.cs 32 23 MVVMVideoPlayer_Test
 
Error 3 Cannot implicitly convert type 'System.Collections.Generic.IObservable<System.Collections.Generic.Event<MVVMVideoPlayer_Test.wsVideos.GetVideosCompletedEventArgs>>' to 'System.IObservable<System.Collections.Generic.IEvent<MVVMVideoPlayer_Test.wsVideos.GetVideosCompletedEventArgs>>'. An explicit conversion exists (are you missing a cast?) C:\Documents and Settings\Administrator\Desktop\Silverlight 4 Code\MvvmVideo\MVVMVideoPlayer_Test\Model\SilverlightVideos.cs 51 17 MVVMVideoPlayer_Test
GeneralRe: My vote of 1memberdefwebserver12 Apr '10 - 12:36 
Dewey wrote:
Well, I wouldn't give this a 1(I think it deserves a 5), but I too am not able to compile this. I get the following error(s).

 
Please install the Silverlight 3.0 RX Extensions from http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx
and try again. Please let me know if this does not fix the problem.
GeneralRe: My vote of 1 [modified]memberVickyC#30 Jan '11 - 4:59 
Nearly a year later, still does not work. They should have a removal of unworkable examples; especially when you ask your readers to correct them.
 

 
-- Modified Sunday, January 30, 2011 11:06 AM
GeneralRe: My vote of 1mvpdefwebserver30 Jan '11 - 5:14 
Installing the Silverlight 3.0 RX Extensions from http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx is not asking users to "fix" a bug. It is a pre-requisite to running the code.
GeneralRe: My vote of 1memberVickyC#24 Oct '11 - 15:55 
still there is no change to facts with your proposal.

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

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 8 May 2011
Article Copyright 2010 by defwebserver
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid