Even a chimp can write code

Sunday, June 08, 2008

Pages in Silverlight

Pages as a paradigm likely pre-date the web itself although they have been popularized by document-based markup languages deriving from SGML. Windows Presentation Foundation (WPF) with XAML further codifies Pages as a first-class UI element from its heretofore usage as a logical element. Looking back from Silverlight, this is as good a point in history to start as any. WPF has built-in support for reusable pages in its applications, and the task of navigation between them. It provides the infrastructure for declarative navigation via hyperlinks or programmatic navigation via NavigationService, and a journal that remembers which pages were navigated to or from. For XBAPs on IE7+, WPF supports integration of the journal with the browser's Back and Forward buttons, while elsewhere it displays a substitute navigation bar with this functionality (the limitation is an effect of how the XBAP host plugs into the browser). There is also a building block called PageFunction which introduces a paradigm for invoking pages as if they were methods, providing a neat little way to build wizard UI. Unlike WPF, Silverlight does not support these things, as of version 2. This post isn't about brooding that absence though -- instead we'll look at the lay of the land in Silverlight 2 with regard to pages and navigation, and look at common workarounds.

Although Silverlight does not have the Page type at this time, the term is currently used for its root visual UserControl. That root visual object is analogous to the root window in WPF, can only be set once for the lifetime of the app, and is effective once the Application's Startup event is raised. The act of navigating from one page to another is similar in principle to the act of removing one child element from an invisible root and adding another child in its place. [Actually given the journal it is more like switching Z-indices between siblings, so that one gets prominence while the other is made inconspicuous]. You can use this same principle in devising the notion of paging in a Silverlight app.


This recipe requires the following ingredients:

  • App.xaml.cs: the code-behind for the Application

  • Frame.cs: a user control which will serve as our "navigation frame". This has no UI.

  • Page1.xaml/Page1.xaml.cs: a user control representing a unique "page". This has a button whose click event navigates away to Page 2.

  • Page2.xaml/Page2.xaml.cs: similar to Page 1 in logic and function, only this represents the second page in your app.

Step 1: Create a navigation frame

This is a really simple user control. It has a public Navigate method which is passed a "page" object for which it duly resets its original content.

// Contents of Frame.cs
public class NavigationFrame : UserControl {

// Navigate the frame to the specified content
public void Navigate(UIElement content)
{
// the existing content of this user control is
// discarded and the specified param is plugged in
// its place
this.Content = content;
}
}

// Optional abstraction for page config
public static class Pages
{
// for simplicity we're using static properties,
// but this could just as easily be a URI to
// Type mapping table
public static UserControl HOME_PAGE = new Page1();
public static UserControl ANOTHER_PAGE = new Page2();
}


Step 2: Wire up the navigation frame as the app's RootVisual

Ordinarily the code generated by Silverlight tools (Visual Studio or Blend) will have a user control hooked up as Application.RootVisual within the Startup event handler. You will change this to hook up the navigation frame. Then hook up the user control to be the navigation frame's content (by invoking the NavigationFrame.Navigate method you created above).

// Contents of App.xaml.cs

// the Startup event handler sets the root visual
private void App_Startup(object sender, StartupEventArgs e)
{
// Navigate to home page
Navigate(Pages.HOME_PAGE);
}

public void Navigate(UIElement content)
{
// Create frame on an as-needed basis
if (this.frame == null)
{
this.frame = new NavigationFrame();
this.RootVisual = this.frame;
}

// Navigate to content
this.frame.Navigate(content);

}


Step 3: Build your pages

Now that the navigation infrastructure is ready, go ahead and create a couple pages. These are merely user controls which would otherwise have been hooked up directly as the RootVisual. That part is simple. An important attribute in this equation is the fact that pages need to provide the experience of "navigating away". You can use a hyperlink, a button, or trap mouse/key events. We'll use a button and insert the navigation logic in it's click event handler.


// Contents of Page1.xaml.cs

// on btn click, this navigates to the second page
private void navigateButton_Click(object sender,
RoutedEventArgs e)
{
(Application.Current as App).Navigate(Pages.ANOTHER_PAGE);
}


Let's create another user control which will be navigated to.


// Contents of Page2.xaml.cs

// on btn click, this navigates to the first page
private void navigateButton_Click(object sender,
RoutedEventArgs e)
{
(Application.Current as App).Navigate(Pages.HOME_PAGE);
}


Well, that's all there is to it really. Build and run, and you've got your simple little navigation application.

In this pattern, the navigation frame element:


  • is the equivalent of the implicit navigation control

  • is a container with no visible visual properties (e.g. Background, etc.)

  • has only a Content element representing the current page


In the pattern, the page element:


  • is the equivalent of the navigable Page

  • has visuals or contains visual elements

  • can be attached and detached from the tree on a navigate event (i.e. the current element is removed, and a new one added in its place)

Our example used the Navigate By Object approach. Note that we invoked the Navigate method and passed it a page object. You could tweak the logic so your pages can be given data as part of the Navigate call. You could just as easily add URI-to-type mapping into the Pages utility type. That would allow you to replicate the Navigate By URI approach which is more organic to content on the web. If you use the Navigate By Object approach and you have a journal that maintains a back/forward stack of pages you've previously navigated to, you can incur a working set hit. This is because your journal will retain references the page objects in memory for long intervals - usually the life of the app - preventing the garbage collector from reclaiming them. Using the Navigate By URI approach in such situations can offer better use of memory. This is because you can delay instantiation of page objects until when the Navigate needs to happen.


In closing, there is a good case for pages, navigation service, journalling, transition animations, deep linking etc. to be part of the Silverlight platform. This is certainly of interest to us as we look toward the next version of the runtime and it's framework. I'd like your thoughts and feedback on these features and how important they are to your scenarios.


Further reading:


PS: For Ben. Sorry this has been long overdue.

PPS: Thanks to Michael Weinhardt for valuable insights.


Update [06/16/2008]: Dave has a new post on navigation with transition effects. Link under the Further Reading section above.

Labels: , , ,

Email this | Bookmark this

Tuesday, May 13, 2008

WPF 3.5 SP1: Don't let the SP moniker fool you

Yesterday the WPF team shipped some major horsepower features in the vastly understated preview Service Pack to .NET Framework 3.5. It is an exception to the rule for an SP release to have features, and not just bug fixes. In the mold of Windows XP SP2, this SP of .NET Framework 3.5 is chock full of new WPF features.

For the first time the .NET Framework has been divided into a Client profile which - intuitively - does not contain server specific libraries such as ASP.NET. This cuts down the size of the .NET Framework to about 25MB (which as Dr. Sneath reminds us is close to Adobe Reader's size) and people like me with a Java background can associate it loosely with the Java SE and Java EE split. In many ways, this is the realization of the Longhorn-era "WinFX" give-or-take a couple assemblies.

Given my previous association with the WPF Application Model, I'll begin with a shout out to improvements from and driven by that crew. The Web Browser control in WPF is embodied by the Frame element. There's new support for interop between WPF and HTML content hosted within it (yay for DOM and script access!). In addition to the existing support for rendering HTML content via URI comes new support for rendering HTML via a stream. This allows for dynamically created HTML content to be rendered in a WPF app. And oh, XBAP enthusiasts will note that this all works in the partial trust sandbox. The progress UI on XBAP launch gets a perf boost and is now an instant-on UI. There's wide ranging real and perceived perf enhancements in the product that customers will truly love. Besides, there are some ClickOnce improvements allowing you to customize the activation error experience, suppress/customize the ClickOnce UI, set up file associations (yes, despite my reservations to this), opting out of signing your apps (I've long maintained that shelling out 300 bucks for a cert is good news for Verisign and gang but bad tidings for hobbyist developers; good to see this change) but with support for corps to block unsigned apps (so this is a wash security-wise). And yeah, ClickOnce-deployed apps can be launched with a click of a hyperlink on Firefox! 

An update to Visual Studio 2008 now lets you target your apps specifically to this Client profile of .NET Framework. You have an option of packaging up your app in an installer which will bootstrap .NET Framework 3.5 and uses some nifty tricks (like asynchronous NGEN) to speed up the time between the click and bits showing up on screen.

This release contains the graphics features demoed at Mix 08, like extensible shader effects which will let you harness the power of the GPU while still using animation, data-binding, media, composition and other WPF goodness. Fittingly, as has been WPF's charter, these features bring advanced concepts like HLSL effects and SIMD processing to the realm of application developers like me with simple abstractions and none of the complexity (I mean creating an effect is still the realm of experts, but using it is as simple as instantiating a control in WPF which I'm perfectly capable of doing, equating it with something like a DataGrid). Besides, there's deeper DirectX integration so you can blend or overlay D3D content with WPF.

There's a new DataGrid and Office Ribbon control provided out of band with WPF.

I can go on and on, but I should stop now because I can't hold this smile much longer. The WPF and other partners contributing to .NET Framework kick some major bootay with this release. Calling it a Service Pack is a classic understatement. Readers who are familiar with Silverlight, but not so much with WPF are encouraged to dig deeper. And do let us know which of these features you'd like to see in Silverlight.

Further content:

Labels: ,

Email this | Bookmark this

Thursday, June 21, 2007

nibbles: snack tutorials for hungry designers


Celso Gomes has a new site up called nibbles: snack tutorials for hungry designers.
In his words:
The concept of nibbles is simple: snack tutorials for hungry designers. The tutorials will teach a few steps at a time, so they will be short and easy to follow - the perfect creative snack.

There are a few tutorials on using Expression Blend and Silverlight already up, with content on Blend and WPF coming soon. New additions will be announced on the nibbles blog.

Labels: , , , ,

Email this | Bookmark this

Wednesday, May 30, 2007

Microsoft Surface: What WPF Can Do For You

Microsoft Surface
Today Microsoft announced the Surface, a new line of consumer products that turn "an ordinary tabletop into a vibrant, dynamic surface that provides effortless interaction with all forms of digital content through natural gestures, touch and physical objects. Beginning at the end of this year, consumers will be able to interact with Surface in hotels, retail establishments, restaurants and public entertainment venues." If the videos on the Surface website seem impressive, you haven't even scratched the surface yet. Using the real product is way cooler!

The Surface team has thus far been operating under the radar. I'm proud to say that the device runs a variant of Windows Vista and uses Windows Presentation Foundation (WPF) for its user experience. It shows how WPF can be a game changer when you exploit its power. It is understandable that the first generation of the product - shipping in the second half of 2007 - is out of reach of the average consumer, and is focused on businesses. I expect that in a couple iterations, component prices, usage scenarios and its economic network will work their way to the mainstream. We've seen that story before. These are good tidings for designers and developers; as Rob points out, this is a "nice device to leverage some of your WPF programming skills on!". This is a great time to pick up and hone those WPF, Silverlight and Expression tools skills.

Congratulations to our friends in the Surface team on the public unveiling of a fantastic product.

Labels: , , , , ,

Email this | Bookmark this

Monday, April 16, 2007

Silverlight Trivia

The name

We've been dropping little hints about the name for months now - the MIME type for the browser plug-in in the Feb CTP was application/ag-plugin and the script instantiation used a new agHost(...) call. Ag  (short for Argentum) is the symbol for Silver in Mendeleev's Periodic Table of Chemical Elements.


Silver
47
Ag
107.8682


 

The .NET connection

Yes, Silverlight extends the reach of the CLR and .NET Framework to other platforms like the Mac! Details coming soon.

Labels: , , , ,

Email this | Bookmark this

Saturday, April 14, 2007

WPF College Courses

I was happy to learn [via Lee] that the FootHill College of Los Altos, CA is offering introductory courses on Windows Presentation Foundation and other .NET technologies. The courses include one on .NET Deployment that I'm guessing (I couldn't find a syllabus for that) includes ClickOnce, the most superior application deployment technology out there for rich client apps.

This is a great opportunity for anyone in the Bay Area wanting to pick up on Microsoft's next generation presentation sub-system and framework APIs.

Cal Schrotenboer, the instructor for these courses, says the cost for California residents is $100 for a class. And since these classes are also offered in an online format, you can enroll from anywhere.

Labels: , , , , ,

Email this | Bookmark this

Saturday, March 17, 2007

Software Branding

I was pleased to see the updated Windows Vista User Experience Guidelines introduce a section on Software Branding. I firmly believe the secret sauce behind every successful software application is the emotional chord it strikes in the end user. Too often we, the sausage makers, focus too much on the technical aspects and too little on the emotional aspect of the software we build.

For something that is frequently overlooked or gotten wrong, this article on software branding is chock full of common sense. Although the examples use Windows artifacts, the guidelines apply very broadly to software we all create.

On another note, I am happy to see this idea dawn on folks across Microsoft. Now if we can strike the right balance between the whole technical v/s visceral v/s behavioral v/s reflective aspects, it'll portend good things to come. The innovations in the Shell in Windows Vista, and platforms such as WPF and WPF/E will surely help.

Labels: , , , , , ,

Email this | Bookmark this

Expression Blend is Release Candidate

The Expression Blend team quietly announced their excellent designer surface for Windows Presentation Foundation went to Release Candidate status. The new build has a bunch of fixes but no new features (that I'm aware of) over the most recent CTP. It does however introduce some spectacular starter samples built using Blend. If you have a creative bone in you, I really recommend downloading Blend RC and taking it for a spin. Either way, check out the ClickOnce powered online samples that the ever resourceful Karsten has posted. I know Robbie and Nathan are impressed.

Labels: , ,

Email this | Bookmark this

Times Reader Goes Subscription

The New York Times announced that the Times Reader application's Beta period ends soon and it will be be converted to a $14.95 / month subscription service that will include Times Select and Premium Crosswords, which were previously paid content anyway. Also apparently home delivery customers of the paper will now get the Times Reader for free. Rob gives his perspective on the pricing. I suspect the Times is just testing the waters here. Of course they're in the subscription business to stay, but I wouldn't be surprised if they factor in usage data and tweak the model to accommodate the potentially diverse user base. Let me tell you, there's more method than madness behind SKU differentiation.

Labels: , , , ,

Email this | Bookmark this

Monday, March 05, 2007

Using WCF In An XBAP

Steve Maine confirmed to Rob and me that Windows Communication Foundation (WCF, codename "Indigo") will work in partial trust in upcoming .NET Framework v3.5. This means you can now use HTTP binding in WCF from within a XAML Browser Application (XBAP).

What does this mean? Well, using WCF you will now get parity for things for which you have been using ASMX within your XBAP. Secure communication is possible via transport layer security only.

Not all WCF features are available from within an XBAP though. This means you cannot currently host services, have duplex communications, use non-HTTP transports, or use WS-* protocols. Please use the WCF Forum or the WPF Forum to tells us what you think. We'd love to hear your feedback on this feature.

For the differences between ASMX 2.0 and WCF, see this article. If you already have ASMX services for which you were using an ASMX client, here's how to migrate ASMX to WCF. I should add, you are already able to access a WCF service using an ASMX client.

Labels: , , , ,

Email this | Bookmark this

Tuesday, February 27, 2007

WPF/E vs DHTML vs Flash vs WPF performance test

Rob sent a link to this post by Alexey Gavrilov who did some benchmarking on a variety of client technologies: DHTML, Flash, WPF/E and WPF. Alexey summarizes the test results thus:

Here are results I got testing with 16 [animated bouncing] balls on my Pentium M 1.7 laptop:

Browser DHTML Flex WPF/e WPF
IE 6.0 56 61 84 99
Firefox 2.0.0.1 55 52 58 -
Opera 9.01 94 50 - -
[...] WPF/e is much faster in IE than in Firefox, which seems equally slow for all three tests. The expected result is that WPF runs faster than anything else. The unexpected is that WPF/e is faster than Flash despite the fact that it’s been in the market for years.

Since the tests focus on a narrow animation sample, one would be cautious to put too much into the results. Regardless, the findings are very interesting. Alexey has posted sources for the tests so you can run them on your own machine.

Labels: , ,

Email this | Bookmark this

Thursday, February 01, 2007

Great apps powered by ClickOnce

I've posted previously about XBAPs, but here are a couple links to standalone Windows Presentation Foundation (WPF) applications that use the ClickOnce deployment model.

ITN has a cool new news -video application called ITN Hub Player, accompanied by a Windows Vista sidebar gadget. See http://www.itn.co.uk/vista/

OTTO, the 2nd largest online retailer in the world, just went live with a very impressive ClickOnce-deployed WPF application which completely changes the online store as you know it. See http://www.otto.de/vista

This app also uses Windows CardSpace and Windows Communication Foundation (WCF), both .NET Framework 3.0 components and part of Windows Vista.

I love seeing ClickOnce being used in mainstream consumer oriented applications, and will be posting about these more often. And that's not just 'cause my team owns WPF Deployment and works closely with the ClickOnce team. Having had my share of munging around with MSIs, I think ClickOnce is by far the most superior application deployment technology out there for rich client apps on Windows. It provides a sophistocated update mechanism for your apps, taking the pain out of that process. If you haven't heard of it before, or aren't using it in your .NET apps, I think the apps above will make you reconsider.

Labels: , , , , , ,

Email this | Bookmark this

Tuesday, January 30, 2007

Windows Vista: Now In A Store Near You

After "the biggest product launch in Microsoft's history", Windows Vista is now available in a store near you and via fine merchants online. This is a culmination of years of work done by my teams and countless others in Microsoft, hardware & software partners and OEMs. In the WPF team, as elsewhere, we've fervently believed: "if you build it, they will come". So although I don't claim to speak for Microsoft on this blog, above all, a big shout out to all of the developers and creative professionals who patiently evaluated our CTPs, Betas and the like and gave us great feedback; and to the people who continue to bet their businesses on our platforms, frameworks and APIs. Thank you for your support. Please keep telling us what we're doing wrong, and what we're getting right. Here's to building applications we've dreamed of!

Tags: , , , ,

Windows Presentation Foundation, is the next generation presentation sub-system and managed code framework for Windows. It is a .NET Framework 3.0 component, present on Windows Vista and a free download for Windows XP SP2 and Windows Server 2003.

Labels: , ,

Email this | Bookmark this

Thursday, January 25, 2007

Xceed WPF DataGrid - For Free

For real. WPF didn't ship with a DataGrid control in .NET Framework 3.0. The fine folk at Xceed Software recognized that and have now released an enterprise strength WPF DataGrid control to the community. They have a beautiful demo XBAP called Xceed DataGrid for WPF LiveExplorer that lets you see the control in action and use it for yourself.

Get the Xceed DataGrid control. [Requires .NET Framework 3.0 or Windows Vista]

Thanks to Mike for the tip.

Tags: , , , , ,

Labels: , , ,

Email this | Bookmark this

Dominoken

KF sent us a link to this beautiful XAML Browser Application (XBAP) created by Bascule for the Windows Vista launch in Japan:

DOMINOKEN

Requires .NET Framework 3.0 or Windows Vista. I've seen it several times, changing the camera angle and zoom settings. Never gets old!

Tags: , , , , ,

Labels: , , , , ,

Email this | Bookmark this

Monday, January 08, 2007

The new Yahoo! Messenger for Windows Vista

It has been tough to keep this one under wraps but I can finally talk now. Yahoo! is shifting the communication and instant messaging landscape. The new Yahoo! Messenger for Windows Vista is one of those seminal applications that demonstrate what good user experience really is. See the video and decide for yourself. This application is built on Windows Presentation Foundation (a .NET Framework 3.0 component and part of Windows Vista).

This isn’t just a re-skinned version of the existing messenger app... this was built by Eric and his ace team from the ground up. A tip o’ the hat to Karsten for tirelessly making sure all of Yahoo!’s questions and concerns were responded to promptly; whether he was hunting us down via discussion lists or on the phone or even setting up face to face meetings, Karsten was a bull-dog you couldn't get away from. Props to the good folk from frog for the kickass design.

This app is a powerful showcase for WPF and Windows Vista features and a testament to how designers and developers can work together on building great applications.

Tags: , , , ,

Labels: , , , ,

Email this | Bookmark this

Saturday, December 03, 2005

More on resource loading in WPF

I recently posted an entry on Resources in Windows Presentation Foundation. That topic covered a whole gamut of things such as Resource and Content build actions and referencing files at an application's site of origin without using a hardcoded URL. I also talked about why you would use one approach over the other.

Andrey Skvortsov commented on that post: Could you elaborate more last variant with pack:// uri syntax for local windows app?You were speaking about win apps and suddenly jump to web based deployment model though it's completly different things IMHO.

I had touched ever so briefly on the Pack URI syntax but didn't give details because I figured that was a whole different topic on it's own, and was much better addressed by the XPS (a.k.a Metro) specification. However, I will try to clarify the issues he's raised.

Pack URIs
The Metro package is a logical entity comprised of a number of parts. The Pack URI scheme defines a way to use URIs to refer to part resources inside a Metro package. It uses RFC 2396's (Uniform Resource Identifiers: Generic Syntax) extensibility mechanism for defining new kinds of URIs based on new schemes. You're probably aware that the scheme is the prefix in a URI, e.g. http, ftp. So Metro defines pack as a new scheme. The URI format is so:

pack://<authority><absolute_path>

The authority component in a Pack URI is itself an embedded URI pointing to a package. This must be a legal URI per RFC 2396. Of course, since it is embedded in the Pack URI, you must escape reserved characters. In our case, slashes ("/") are replaced by commas (","). Other characters like "%", "?" etc. must be escaped. See the spec for complete details. Windows Presentation Foundation provides an application with two built-in authorities: application and siteoforigin.

The application authority abstracts the deployed application itself. Any resources embedded in that application assembly, one of it's satellite resource assemblies or even loose files accompanying that application may be referenced using this authority. Of course, your project must define these files as Resource and Content, respectively. I should add though, that you need not use the Pack URI syntax for application files such as these. You can just use regular relative URIs.

The siteoforigin authority abstracts the conceptual site of origin of the deployed application. So if you had a file test.jpg at the location where the application binaries and manifests reside, say C:\myfiles\, then you need not hardcode the URL file:///C:/myfiles/test.jpg. You can instead use the abstraction pack://siteoforigin:,,/test.jpg. Notice that I said need not: in a full-trust application (Window-based installed application), you can do pretty much what you want. But in a web-browser application, you cannot access files on disk so adding a reference such file:///C:/myfiles/test.jpg pretty much binds you to a full trust app, and moreover you have to worry about how to get that image into that location for everyone that uses your app.

So, to go back to Andrey's question, if he were prototyping a WPF app, it would be prudent to use these abstractions and make the app portable, no matter if the prototype started out an installed or browser-hosted app flavor. Remember that with WPF, you use the same programming model for an installed app and a browser-hosted app. You can switch between these two flavors merely by changing the HostInBrowser and Install properties in your project, and pretty much nothing else. Besides, ClickOnce does the heavy lifting of downloading all loose content files for your application during deployment, so you don't have to.

Is there an easier way to construct Pack URIs?
Yes, look at the System.IO.Packaging.PackUriHelper class and try experimenting with the Create method by passing it different types of URIs as parameters.

You don't really need Pack URIs
That's right. The novice WPF programmer can survive without knowing how Pack URIs work. I've talked about how you can use simple relative URI references instead of the pack://application notations. Further, if you're looking for a package part or better still, the stream for an embedded resource you can use Application.GetResourcePart(Uri relativeUri). To get a stream for an XML file embedded in your application:

Stream stream = Application.GetResourcePart(
new Uri("RssFeed.xml")).GetStream();

To get the stream for a loose content file you can use Application.GetContentPart(Uri relativeUri). For e.g. here's how to get a stream for a declared loose image file with your application:

Stream stream = Application.GetContentPart(
new Uri("MyImage.jpg")).GetStream();

To get the stream for a file at the location from where the application was launched, you can use Application.GetRemotePart(Uri relativeUri). For e.g. here's how to get a stream for an undeclared text file at the site of origin:

Stream stream = Application.GetRemotePart(
new Uri("Contacts.txt")).GetStream();


Update [Apr 2009]: If you came here looking for resources and URIs in Silverlight, then you will find this post helpful. Note that Silverlight does not support pack URIs.



Tags:

Labels: , ,

Email this | Bookmark this