Even a chimp can write code

Tuesday, March 11, 2008

How to tell the screen resolution from within a Silverlight app

There isn't a direct API for detecting the screen width and height from within a Silverlight app. Fortunately, JavaScript provides you a way, viz. via the screen.width and screen.height properties. So with a nifty use of Silverlight's HTML DOM Bridge, these values can be read with little issue.

int screenWidth = Int32.Parse(

HtmlPage.Window.Eval("screen.width").ToString()

);

int screenHeight = Int32.Parse(

HtmlPage.Window.Eval("screen.height").ToString()

);


Then when your app runs in fullscreen mode, you'd get the screen resolution using the Silverlight plug-in's ActualWidth and ActualHeight.

int screenWidth =

Application.Current.Host.Content.ActualWidth;

int screenHeight =
Application.Current.Host.Content.ActualHeight;

Labels:

Email this | Bookmark this

Silverlight 2: Demystifying URI references for app resources

In this post we will look at how application data files can be referenced using relative Uris from within XAML or code in your Silverlight 2 application.

Silverlight provides you with a luxury of choices for how you declare your application data files. These are the non-code artifacts of your app, such as images, videos, fonts etc. The build action for any file - i.e. how you declare it in your project file or within Visual Studio or Blend - is consequential to how it can be referenced in XAML or code via a Uri. While care was taken to ensure defaults that gel with the programmers intuitiveness while referencing them in Uris, there are always subtle issues that the intrepid Silverlight designer or developer must be aware of. If you come to Silverlight with previous WPF experience, the contents of this post should be old news to you. If not, fear not; Silverlight is designed to be easy to learn and easy to master.

Let's take Image files as an example as we walk through the various cases. Once you understand how this works, you can extrapolate behavior for MediaElement (audio/video) or MultiScaleImage (SeaDragon in Silverlight) or perhaps even fonts. While examples below show XAML syntax, the same applies to code.

Files marked as Resource:

  • Get embedded in the app assembly within the XAP
  • Are accessible using a relative Uri, relative to the XAML file from where they are being referenced
    For e.g. <Image Source=”Foo.jpg” />
  • When not found, there is no fallback. The ImageFailed event is raised.

Tip: Using assembly qualified Uris is most reliable both from within and outside that assembly. E.g. <Image Source=”/{assemblyShortName};component/Foo.jpg”/>

Tip: You can programmatically extract any application resource using Application.GetResourceStream(uri).Stream.

Files marked as Content:

  • Get added to the XAP at the conceptual application root
  • Are accessible using a relative Uri, relative to the application root. This requires the use of a leading slash
    For e.g. <Image Source=”/Foo.jpg” />
  • When not found, the resource loading mechanism falls back to the application’s site of origin and looks for the image under the same (web root) dir as the XAP is located
  • When not found, the ImageFailed event is raised.

Tip: this is a no-brainer when you have a resource that is commonly used from within 2 assemblies in the XAP

Files marked as None (with CopyToOutputDirectory set appropriately):

  • Don’t get copied into the XAP, but the CopyToOutputDirectory metadata will ensure it gets copied alongside the XAP
  • Are accessible using a relative Uri, relative to the application root. This requires the use of a leading slash
    For e.g. <Image Source=”/Foo.jpg” />
  • This is the fallback path of the above

Tip: in most cases you want to keep your video files out of the XAP. They are not encumbered by x-domain download restrictions. You do not get compression benefits from keeping them in the XAP. Rather you can use streaming or progressive download if they are outside.

Files marked as None, as well as image and audio/video files not marked at all in the project (i.e. external to the project), can always be referenced using absolute Uris.

Files marked as EmbeddedResource:

  • Get embedded into the assembly in a manner that Silverlight cannot use for URI references either from XAML or code
  • Should be changed to Resource, and used as detailed above.

Hopefully this demystifies Uri usage in Silverlight for you. If we can make improvements in the runtime or in tools to make this easier for you, please post a comment here. Feedback is always appreciated.



    Related links:

    Labels: , , , ,

    Email this | Bookmark this

    Transcoding media files for Silverlight

    Silverlight supports Windows Media Audio and Video (WMA, VC-1/WMV7-9) and MP3 formats. If you have existing media assets in other formats, you can convert them into a format Silverlight can understand. There are a couple ways to do this.

    On your desktop using Expression Encoder

    • Use the user interface for granular control over the entire user experience on your media files with support for encoding, enhancement and publishing for Silverlight
    • Or use the command line interface for batch processing
    • Choose this when you do not have abundant bandwidth to upload media assets to Silverlight Streaming for encoding or transcoding
    • Choose this if you have adequate CPU power on your desktop to transcode your assets
    • Expression Encoder can upload your media files to the Silverlight Streaming service using this plug-in

    In the cloud using Silverlight Streaming

    • The companion service to Silverlight on the cloud at http://silverlight.live.com/ provides transcoding support in the Video Management area
    • Choose this if you have enough bandwidth to upload (unencoded) media assets to the cloud
    • Choose this if you do not have adequate CPU power on your desktop machines to efficiently encode/transcode media assets
    • Choose this if you would like to offload your media hosting to Microsoft's high performance, geo-scale content delivery network (CDN)

    PS: my one gripe is that the Silverlight Streaming SDK docs do not explicitly say which file formats it can transcode for you. I know they support .mov, but what about .flv? Hoping they fix this soon.

    Update [3/12/2008]
    : Thanks to Anoop Anantha, WL Platform Architect, I've now learned that Silverlight Streaming will transcode mpeg2, mpeg4, divX, H.264, flv formats, among others, to a Silverlight-friendly wmv format. He mentioned they will be updating the docs.

    PPS: tip o' the hat to Angus Logan for his excellent talk at Mix 08 on Windows Live services.

    Labels: , , , , ,

    Email this | Bookmark this

    Monday, March 10, 2008

    How to pass initialization params to a Silverlight 2 app

    This is something of an FAQ on our internal discussion lists, so I figured it merited a post.

    Step 1: Declare the initParams param on the Silverlight plug-in and pass in a comma-delimited set of key-value pair tokens. For e.g. "key1=value1,key2=value2,key3=value3".

    <object type="application/x-silverlight"
            width
    ="100%" height="100%">

      <param name="source"
             value
    ="ClientBin/SLInitParams.xap"/>

    <!-- startPage key can have values Page1 or Page2 -->

      <param name="initParams"
             value
    ="startPage=Page1" />

    </object>

    For best results, the key and value tokens in the initParams string must be restricted to alphanumeric values. There currently isn't support for escaping equality signs or commas, for instance, should they exist in the key or value part of the token.

    Step 2: In the Application's Startup event handler, extract the initialization parameters via StartupEventArgs.InitParams property. You'll get an IDictionary<string, string>.

    // Contents of App.xaml.cs

    private void Application_Startup(object sender,
                                       StartupEventArgs
    e)

    {
        string startPage = e.InitParams["startPage"];
        if (startPage != null && startPage.Equals("Page1"))

        {
           // Load Page1
           this.RootVisual = new Page();
        }
        else
        {
           // Load Page2
           this.RootVisual = new AlternatePage();
        }
    }

    Simple, huh? I have a sample project on how to pass initialization params to a Silverlight 2 app, and conditionally show UI, up on my sky drive.

    Labels:

    Email this | Bookmark this

    Silverlight 2: Application model

    The first public beta of Silverlight 2 is now live. If you've played with building apps on it, you know we weren't kidding when we used the "Windows Presentation Foundation / Everywhere" moniker. Although we didn't inflict that monstrosity of a name on you, we did bring much of the sheer goodness of WPF in the APIs, the depth of functionality, the extensibility points and the overall experience designing or developing one of these babies.

    In this first installment of a series of posts on Silverlight 2 features, I'll talk about the new Application Model. I'll loosely define an Application Model as "the principles on what constitutes an application, how it's lifetime is governed, and the set of services offered by a platform or runtime to the application". The Silverlight 2 Application Model borrows heavily from that of WPF. And it's goals are to be simple and predictable, to provide extensibility hooks, and otherwise to stay out of the way.

    The Silverlight 2 application
    The Silverlight 2 application is a client-side entity running within the confines of a host such as a browser. It is a packaged archive -- we use the Zip data compression and archival format -- with the .xap file extension and application/x-silverlight-app MIME type. Despite the introduction of this new application file, the Silverlight 2 runtime continues to support vanilla XAML content specified via file Uri or inline reference to SCRIPT block a la the v1.0 programming model.

    Here's an outline of the features supported in the new application model:

    • New application package unit
    • Encapsulation of application functionality in a type deriving from System.Windows.Application, along with app definition XAML
    • Application lifetime: ctor, Startup event, Exit event
    • Handle exception conditions in a central location at the app level
    • Support for declarative dependency downloads, as well as programmatic for more granular control
    • Utility methods to extract app resources or resources from arbitrary Zip packages
    • Access to the Silverlight plug-in's object model via the Host property
    • Default splash screen provided by the platform, with ability to override it using custom XAML and JavaScript
    • Support for activating a Silverlight application from cross-domain (x-domain) to HTML page; secure by default, and ingress/egress need to be opted into.
    • Ability to refactor application functionality into individual pieces, daisy-chained together and dynamically loaded at runtime

    A more detailed overview of the new Silverlight 2 application model is provided in this slide deck I've posted on my sky drive. The Silverlight 2 application model documentation on MSDN is a must-read. As always, feedback is appreciated. You can drop a comment here or post on the Silverlight forums.

    Labels: ,

    Email this | Bookmark this