views:

32

answers:

1

I'm in the process of removing the XAML from my Silverlight project and making it use only code (as per this article).

Here is my very simple startup event for a Silverlight application (with the standard App.xaml from the template project):

private void Application_Startup(object sender, StartupEventArgs e)
{
    Grid grid = new MainPage();
    this.RootVisual = grid;

    var mediaElement = new MediaElement();
    mediaElement.MediaFailed += (s, ea) => { mediaFailed = true; };
    mediaElement.Source = new Uri(@"/Content/Some Music.mp3", UriKind.Relative);
    grid.Children.Add(mediaElement);
}

Where the MP3 file is set to "Build Action: None, Copy if newer" (ie: it's beside the XAP). Here's the XAML for MainPage:

<Grid x:Class="TestGame.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
</Grid>

And the C# - nothing unusual here at all.

public partial class MainPage : Grid
{
    public MainPage()
    {
        InitializeComponent();
    }
}

That all works so far. So my question is this: why is it that when I change

Grid grid = new MainPage();

to

Grid grid = new Grid();

the mediaElement.MediaFailed event gets called (with a AG_E_NETWORK_ERROR)?

The only interesting thing that InitializeComponent is doing is calling Application.LoadComponent (it's the default generated code). So what might that function be doing that allows source URIs to work?

It seems that Application.GetResourceStream still works just fine. But I need to be able to get a few resources external to the XAP.

(Note: it seems this guy is having the same problem - but no one answered his question.)

+1  A: 

The key factor is UriKind.Relative. The question is to what is it relative?

One of the effects of LoadComponent is that it shifts the location of "/". Before LoadComponent executes the path "/" refers to the same location as it would do in the host browser. After LoadComponent "/" refers to a hybrid of the root contents of the Xap and the folder that contains the Xap.

Since you are running this via a standalone test html page "/" in your second example refers to the root of the physical drive, e.g. "c:\".

If you change the Url to "Content/Some Music.mp3" (that is remove the "/" prefix) and assuming your test html page is the same folder as the Xap it should work as expected.

Note you can't escape the hybrid path with the parent path "..", Silverlight doesn't let you do that.

AnthonyWJones
Thanks for the explanation. For everyone's reference, here's the http://msdn.microsoft.com/library/cc296240(VS.95).aspx documentation your answer lead me too (I'll have to re-read it myself later, it's pretty obtuse and I don't fully understand it yet). I think in my case I will just have to have some XAML - because my deployed XAP (and associated content) will be referenced from HTML at an unspecified URL.
Andrew Russell