Plip's Weblog

Phil Winstanley - British .NET chap based in Lancashire. Enjoys tea and tech. Working for Microsoft.

November 2007 - Posts

MSDN In English

Dear Subscriber

Following customer feedback we are pleased to announce that Microsoft will be creating new MSDN media language packs. The purpose of these new language packs is to provide you with a choice and enable you to receive only the languages you require. This is an alternative to the current process where many customers receive all languages, many of which they do not need.

While implementing these new packs we are also reviewing all existing customer MSDN media language pack options and notice that you are currently subscribing to the Euro all offering. Many customers on these packs today complain about the volume of media received.  In an effort to address this, and to make your subscription easier to manage we are planning to update your media pack to English from the January shipment. All other languages offered will continue to be available online for download.

If you have any questions with respect to this upcoming change, you can contact the MSDN Information Center, who will be happy to provide more information.

Yours Sincerely,

The MSDN Subscriptions Team

Building WPF Applications with the Page Navigation framework (It's just like ASP.NET but with state...)

As I'm sure many of you are aware, this is an ASP.NET blog site, and I (allegedly) am an ASP.NET Developer, so what, you might be asking yourself, would I have to say on WPF applications that might be of value?

Well, recently I've had to forge ahead building my first WPF application which was an interesting learning experience, so I'd like to share that experience and the tips and tricks I've gleaned from the blood, sweat and tears which now sits in a congealed pool beneath my development laptop.

As with all religious journeys of discovery, there's a holy book to help with guidance and sage advice. For my pilgrimage into the distant lands of Windows application development I selected and read from the sacred book of Windows Presentation Foundation Unleashed.

The book is truly one of the best technical tomes I've ever had the pleasure of reading. I picked it up and read the book cover to cover over the course of a few evenings; it prepared me for WPF and did so in a way that enabled me to start thinking about how to build my application whilst leafing through page after page of detailed descriptions and expert knowledge.

 

Windows vs Pages

If you're an ASP.NET developer like myself, then you're familiar with the concept of pages and links and the general way in which navigation works. In turn, it's possible you know nothing about the way in which Windows (of the XAML variety) work, how to move from one to the next and generally make an application look and feel seamless. That's the position I approached this from.

As mentioned above, in the sacred works of Adam Nathan, I gleaned detailed technical knowledge of WPF and how it all fits together. In doing so, I happened upon a chapter which detailed the Page based model in WPF. I'd never heard of this approach and phrases leaped at me from the pages, burning into my consciousness. Phrases like "Frame" and "Link", "Uri" and "History". Before long I was wrapped up in a familiar environment and was certain that for my application (content heavy) building it with the Page framework was absolutely essential.

Not only did the Page model fit my mind set, but also my skills set and that of my colleagues (Web Designers). We could build an app in a way which was familiar whilst taking benefit of all the great functionality you get from WPF.

Now, you might think different, but as I said earlier, this is my first WPF application and it felt "right" to go down this direction.

 

NavigationService

Unlike HTML pages where you can just slap an anchor into the code to allow linking: -

<a href="Blah.htm">Blah</a>

Or even just use a little bit of JavaScript to navigate around:-

window.location.href = "Blah.htm";

There's a lovely little service inside WPF which helps with Navigation, and it's, unsurprisingly, called the NavigationService. It's relatively simple to use too.

NavigationService.Navigate(new System.Uri("Blah.html", UriKind.RelativeOrAbsolute));

As well as the appropriately named Navigate there's also a cool range of methods such as GoBack and GoForward as well as a range of events to let you monitor and intercept happenings Navigating, Navigated and LoadCompleted to name just a few.

Using the Navigation service and hooking up buttons or other programmatic devices to the flow of your application is such a natural way to work if you're already familiar with Web Application development.

There's a very simple way to grab a reference to the currently displaying page in your application and then change the Uri currently being displayed, you just need to go up the tree a little before finding the right place: -

((NavigationWindow)(Application.Current.MainWindow)).Navigate(new System.Uri("Blah.xaml", UriKind.RelativeOrAbsolute));

Dirty? Unwindows? Perhaps.

 

Begone Back and Forward Buttons!

It's actually unbelievably simple to hide the Navigation buttons

this.ShowsNavigationUI = false;

This will result in the buttons show here and it's entire bar being removed, which is pretty funky, what you effectively have now is a "popup window"; in my instance, the application is running full screen which with the navigation removed becomes a super sexy user interface.

ForwardBack

 

Wrap up your functionality in a nice warm cuddly user control blanket 

WPF, just like ASP.NET has the concept of Usercontrols, which is excellent, I am a prolific usercontrol user, so much so, Dave Sussman regularly questions why I've used a usercontrol to wrap up even the most page specific of functionality.

Adding a usercontrol is really easy, amazingly so in fact. There's even a template built into Visual Studio for them: - 

 

Add WPF Usercontrol

 

Once the control is all written (here's a sample control I have which is in a different assembly from that of the main application), it's very easy to reference and include in your pages.

<UserControl x:Class="MyControls.AlertLayer"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" GotFocus="UserControl_GotFocus">
    <Grid x:Name="AlertMechanism" Margin="0">
        <Image Source="AlertLayer\Incoming_call.png" Opacity="1" x:Name="AlertImage1" MouseDown="AlertImage_MouseDown" Visibility="Hidden" Stretch="None"></Image>
        <Image Source="AlertLayer\visitor_alert.png" Opacity="1" x:Name="AlertImage2" MouseDown="AlertImage_MouseDown" Visibility="Hidden" Stretch="None"></Image>
    </Grid>
</UserControl>

The reference in the Page tag and the instance looks something like this: -

<Page x:Class="MyPages.AlertScreen"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:lib="clr-namespace:MyControls;assembly=MyControls"
    Title="Alerts"
    >
    <Grid Background="Black" Width="Auto" Margin="0" Opacity="1">
        <lib:AlertLayer x:Name="AlertImageLayer"></lib:AlertLayer>
    </Grid>
</Page>

Cool huh? Just like ASP.NET in terms of the flow and concept.

 

HTML Content and WPF applications

One of the really cool things for web developers is that we can very quickly, using the <Frame /> control, link to and use HTML content we've already built including existing web sites and assets without any changes needed to them whatsoever.

So here we are, with our Frankenstein's Monster of applications, and on cue, the monster goes nuts and tries to kill everyone...

This is where my application came a little unstuck, you see, the <Frame /> control in WPF is the least WPF control in the toolbox, in fact, it's not WPF at all, but rather just seems to create an ActiveX Internet Explorer object which is embedded into your application.

The result of this is somewhat irritating; the <Frame /> when containing HTML content can't be overlayed with WPF content. Not only that, transforms don't work. This problem is detailed elsewhere, here's an example.

 

Don't touch the edges!

One problem I ran into whilst trying to embed HTML within my WPF application was the existence and stubbornness of the borders which the frame's were showing when pointing at HTML content.

As the application I was writing had to load both local content (HTML pages on disk) and remote content (out in the wild and uncontrollable web it's self) I had to solve this problem in rather a novel way as the only way you can disable the borders (which I could find) was the actually modify the HTML of the pages you're loading.

WPF Cross Section

As you can see from the above, no frame border is visible on the frame and it's HTML content butts up smoothly with the outer WPF content, in fact, the above image is labeled slightly misleadingly, the dark gray bar inside the Frame section is actually WPF, whereas the two lighter gray bars are actually HTML, can you see the join? (That's a rechtorical question, of course you can, they're different colours, but that's all part of the design of the application, it could be very easily made the same colour and there'd be no join at all.). 

How was this achevied? Well, through nasty hacking and having pages load pages which have specific styles set up on them: -

Firstly, here's the Frame declaration: -

<Frame Name="ContentFrame" Grid.Row="1" Width="Auto" Height="Auto"></Frame>

Then the code behind for the Page which hosts the Frame: -

string urlToNavigateTo = System.Web.HttpUtility.UrlEncode("http://localhost:30000/Blah.htm");
Uri frameUrl = new Uri(@"http://localhost:30000/BorderRemovingFrame.asp?FrameSrc=" + urlToNavigateTo);
LocalServerManager.StartCassini(); //You can use IIS just as easily we only used a local server as we needed offline access
ContentFrame.Source = frameUrl;

Followed by the ASP.NET/Classic ASP page which does the querystring work (this could also be JavaScript but the QueryString handling is better in ASP.NET), note the style information added to the body element of the page, this is what actually hides the frame border around the frame when linking to HTML pages: -

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
    <head>
        <title></title>
    </head>
    <body style="overflow:hidden;border-style:none;padding:0px;margin:0px;background-color:Transparent;border:0px;">
        <iframe id="innerFrame" frameborder="0" style="overflow:hidden;border-style:none;padding:0px;margin:0px;" scrolling="auto" height="100%" width="100%" src='<%= Request.QueryString["FrameSrc"] %>' />
    </body>
</html>

The Page loaded into the iFrame, in the Frame of the Page ... (erm ... yes, that's right) ... is just a normal HTML page: -

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
    <head>
        <title></title>
    </head>
    <body style="margin:0px;border:none;padding:0px;">
    <div>
      Content Here
    </div>

    </body>
</html>

Messy, but it does appear to work.

Using the above method I build a WPF application which hosted both content as Pages in XAML and HTML; my HTML pages even contained Flash files, which is really funky - WPF loading Flash - with the HUGE amount of Flash content out there, it's great to be able to take advantage of and use it.

 

The Bells!

If you are in control of the devices onto which your applications will run you can modify the Start Navigation sound in windows to prevent the "click" noise every time you move from page to page.

Start Navigation Sound

 

It's all pretty cool. Feel free to share any tips or guidance on how best to use the controls and functionality I've mentioned here. I'm almost certain there are better ways to do things. 

Many thanks to RBT and the designer for their help in putting this application together.

 

Technorati Tags: , ,
Microsoft (MSDN) is now more environmentally friendly

 

Some months ago I wrote a blog post about the MSDN DVD Mountain I was creating at home and how unnecessarily wasteful it was.

Well, Microsoft have listened to us and changed their policy - which is fantastic news for all users of MSDN but also the environment.

 

Msdn Language Packs

 

I'd like to say thanks to Microsoft publicly for taking this action - it was the right thing to do :)

 

Technorati Tags: , ,
More Posts