Plip's Weblog

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

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: , ,

Comments

Granville Barnett said:

Hi Phil,

I thought the best WPF combo was to read one or more of the following:

- WPF Unleashed

- Programming WPF

- Apps = Code + Markup

As well as Essential WPF which is more of why things were done the way they are.

So I would say now read Essential WPF and you should be able to from there master WPF in ever regard.

# November 21, 2007 2:32 PM

Chetan Deshmukh said:

Do you know how to pass query parameter while navigating from one page to other.

I want to navigate from ListProduct page to UpdateProduct page after double clicking on any product from the list.

I want to pass the ProductId to UpdateProduct product page.

      how can I pass the ProductId as an Query parameter Using Navigation.

     Now I am able to use ....

framMain.Navigate(new Uri(@"TabProduct\UpdateProduct.xaml", UriKind.Relative),ProductId);  

How I can retrive the productId at the UpdateProduct page..?

Thanks,

Chetan Deshmukh

Chetan.Deshmukh@e-Zest.in  

# June 30, 2008 12:34 AM

Brandon said:

@Chetan

I dont believe that is actually passing in the Product ID. You'd be better off creating an instance of your class, and then passing that in.

UpdateProduct updateProduct = new UpdateProduct(ProductId);

framMain.Navigate(updateProduct);

Then on your update product page, just have the constructor take in an integer and you can set the product ID there.

# September 5, 2008 5:24 PM

Fred Mackie said:

There are also webcasts on www.microsoft.com/.../msdnnetframework3.aspx about building applications with WPF.

# March 3, 2009 10:31 PM

kamilopoland said:

Hello to all ! Greetings From Poland ! Very nice website.

# August 27, 2009 3:53 PM

carrepossesseion said:

Hi, I can’t understand how to add your site in my rss reader. Can you Help me, please :)

# September 17, 2009 1:57 PM

Robin Carter said:

This brings to mind something that my grandmother always said...

Obviously it's definitely inappropriate right this moment...

# November 11, 2009 2:32 PM

Diana Wood said:

This brings to mind something that my aunt pretty much always said...

Then its most likely not appropriate at this time...

# November 11, 2009 2:59 PM

Patricia Barnes said:

This makes me remember something that my grandfather would always say...

Obviously it is most likely inappropriate at this time...

# November 11, 2009 6:05 PM

Kathleen Robinson said:

This reminds me of something funny that my aunt pretty much always said...

However it is so inappropriate at this time...

# November 11, 2009 6:22 PM

Crystal Adams said:

This reminds me of something my cousin would always say...

Obviously it's definitely inappropriate at this time...

# November 11, 2009 7:31 PM

Alan Fisher said:

This brings back to mind this thing my cousin would always say...

Of course it is totally not appropriate right this moment...

# November 11, 2009 8:16 PM

Judith Patterson said:

This reminds me of something my grandma pretty much always said...

But then its totally inappropriate at this time...

# November 11, 2009 8:22 PM

Carlos Smith said:

This reminds me of this thing my mom used to say...

But then its definitely inappropriate just now...

# November 11, 2009 8:27 PM

Lillian Cooper said:

This makes me remember something that my mother always said...

Then its surely inappropriate just now...

# November 11, 2009 8:34 PM

Timothy Griffin said:

This brings to mind this thing my sister would always say...

But its probably inappropriate right now...

# November 11, 2009 9:27 PM

Kathryn Ramirez said:

This brings back to mind something that my grandma pretty much always said...

Then it's definitely inappropriate just now...

# November 11, 2009 9:31 PM

James Hughes said:

This reminds me of this thing my grandfather pretty much always said...

Obviously its definitely not appropriate just now...

# November 12, 2009 12:32 AM

Judy Patterson said:

This reminds me of something funny that my grandfather would always say...

Of course it is so inappropriate right now...

# November 12, 2009 1:01 AM

Mildred Thomas said:

This brings to mind something that my grandfather used to say...

But then its probably inappropriate right this moment...

# November 12, 2009 1:46 AM

Dennis Russell said:

This brings to mind something funny that my aunt used to say...

Of course its surely inappropriate right now...

# November 12, 2009 3:37 AM

Margaret Garcia said:

This brings to mind something that my brother would always say...

Then it is so not appropriate at this time...

# November 12, 2009 4:07 AM

Donna Foster said:

This brings to mind something funny that my brother would always say...

Of course it is most likely not appropriate just now...

# November 12, 2009 4:17 AM

Tammy Young said:

This brings back to mind this thing my dad would always say...

However it is surely not appropriate right now...

# November 12, 2009 4:23 AM

Laura Parker said:

This reminds me of something that my father would always say...

However it's surely not appropriate right now...

# November 12, 2009 5:28 AM

Ashley Thomas said:

This brings back to mind something that my mom would always say...

However it's most likely not appropriate right this moment...

# November 12, 2009 7:06 AM

ilyash89 said:

I want to quote your post in my blog. It can?

And you et an account on Twitter?

# January 7, 2010 11:47 AM

Kim Salinger said:

Totally inappropriate, all of it

# February 4, 2010 5:23 PM

Na Zdrowie said:

I’ve been visiting your blog for a while now and I always find a gem in your new posts.  Thanks for sharing.

# June 7, 2010 5:12 PM

Wakacje said:

I just book marked your blog on Digg and StumbleUpon.I enjoy reading your commentaries.

# June 19, 2010 4:38 AM

vemma said:

I’ve been visiting your blog for a while now and I always find a gem in your new posts.  Thanks for sharing.

# June 21, 2010 12:38 PM

weightlostpx said:

You certainly have some agreeable opinions and views. Your blog provides a fresh look at the subject.

# July 12, 2010 5:11 AM

vemma4647 said:

Very informative post. Thanks for taking the time to share your view with us.

# August 1, 2010 10:47 AM

legitimate online degree programs said:

Interesting article! I read about this before. Thanks to author.

# September 8, 2010 12:36 PM

สถานที่ท่องเที่ยว said:

Fine information, many thanks to the author. It is puzzling to me now, but in general, the usefulness and significance is overwhelming. Very much thanks again and good luck!

# September 21, 2010 1:39 PM

repocars3668 said:

Very informative post. Thanks for taking the time to share your view with us.

# September 28, 2010 1:34 PM

intranet software said:

You doing a great work for Peace! Keep this up.. You're appreciated!

# October 4, 2010 1:12 AM

vjcuahpd said:

You certainly have some agreeable opinions and views. Your blog provides a fresh look at the subject.

# November 3, 2010 6:57 PM

IrrerceGeld said:

You certainly deserve a round of applause for your post and more specifically, your blog in general. Very high quality material

# November 4, 2010 9:49 PM

lesspoundsydl said:

I just book marked your blog on Digg and StumbleUpon.I enjoy reading your commentaries.

# November 10, 2010 6:06 PM

autoauctions0984 said:

You certainly have some agreeable opinions and views. Your blog provides a fresh look at the subject.

# November 15, 2010 6:30 PM

carauction0697 said:

You certainly deserve a round of applause for your post and more specifically, your blog in general. Very high quality material

# November 15, 2010 10:38 PM

seizedcar9963 said:

I find myself coming to your blog more and more often to the point where my visits are almost daily now!

# November 16, 2010 3:28 PM

antivirusuctrg said:

Very informative post. Thanks for taking the time to share your view with us.

# November 16, 2010 3:34 PM

repocars3636 said:

I just book marked your blog on Digg and StumbleUpon.I enjoy reading your commentaries.

# November 18, 2010 6:51 PM

IrrerceGeld said:

I just book marked your blog on Digg and StumbleUpon.I enjoy reading your commentaries.

# November 18, 2010 7:20 PM

cleanpcgybra said:

I’ve been visiting your blog for a while now and I always find a gem in your new posts.  Thanks for sharing.

# November 18, 2010 10:20 PM

lostpoundsdrz said:

I find myself coming to your blog more and more often to the point where my visits are almost daily now!

# November 19, 2010 12:52 AM

IrrerceGeld said:

Very informative post. Thanks for taking the time to share your view with us.

# November 19, 2010 1:11 PM

IrrerceGeld said:

Very informative post. Thanks for taking the time to share your view with us.

# November 19, 2010 4:56 PM

weightlossmvx said:

You certainly deserve a round of applause for your post and more specifically, your blog in general. Very high quality material

# November 22, 2010 3:19 PM

fatburnlsm said:

I just sent this post to a bunch of my friends as I agree with most of what you’re saying here and the way you’ve presented it is awesome.

# November 25, 2010 2:54 AM

saqt said:

Thanks for taking the time to share your view with us.

# November 26, 2010 1:43 AM

governmentauction6233 said:

You certainly deserve a round of applause for your post and more specifically, your blog in general. Very high quality material

# November 27, 2010 7:08 PM

spywaregkjvz said:

I find myself coming to your blog more and more often to the point where my visits are almost daily now!

# November 27, 2010 10:17 PM

autoauctions7111 said:

I just book marked your blog on Digg and StumbleUpon.I enjoy reading your commentaries.

# November 27, 2010 11:44 PM

Melissa McLaney said:

Ne'er cast a clout till May be out

# December 8, 2010 1:57 PM

game said:

I’d have to give blessing with you on this. Which is not something I typically do! I love reading a post that will make people think. Also, thanks for allowing me to comment!

# December 13, 2010 10:36 PM

ipad accessories wholesale said:

Good is good, but better carries it.

-----------------------------------

# December 19, 2010 9:59 PM

ipad app reviews said:

-----------------------------------------------------------

"Hrmm that was weird, my remark obtained eaten. Anyhow I desired to say that it's nice to find out that another particular person furthermore talked about this as I had bother discovering the same info elsewhere. This was the first place that instructed me the reply. Thanks."

# January 3, 2011 7:18 PM

ownessert said:

I’ve been visiting your blog for a while now and I always find a gem in your new posts.  Thanks for sharing.

# January 9, 2011 11:27 PM

nolvadex 20 mg said:

If you can't be good, be careful

# January 17, 2011 8:48 PM

Citrato de Tamoxifeno said:

Do as I say, not as I do

# January 18, 2011 7:36 PM

vordPoivy said:

I just book marked your blog on Digg and StumbleUpon.I enjoy reading your commentaries.

# January 20, 2011 2:52 PM

vordPoivy said:

I’ve been visiting your blog for a while now and I always find a gem in your new posts.  Thanks for sharing.

# January 21, 2011 5:36 PM

greeroSek said:

I just book marked your blog on Digg and StumbleUpon.I enjoy reading your commentaries.

# January 25, 2011 5:06 PM

jernjerpige said:

Very informative post. Thanks for taking the time to share your view with us.

# January 26, 2011 6:37 PM

QUITUISOTONUT said:

I’ve been visiting your blog for a while now and I always find a gem in your new posts.  Thanks for sharing.

# February 24, 2011 10:32 PM

ZepUlcete said:

Very informative post. Thanks for taking the time to share your view with us.

# April 3, 2011 1:37 PM

nubPagbainG said:

I’ve been visiting your blog for a while now and I always find a gem in your new posts.  Thanks for sharing.

# April 19, 2011 6:38 PM

best 2010 iphone apps said:

"Virtuous what I used to be seeking and quite thoroughgoing as surface. Many thanks for placard this, I saw a yoke diverse associated posts but yours was the optimum  up to now. I outlook it stays updated, enjoy worry."

--------------------------------------------------------------------        

Chemical Biology

# April 27, 2011 7:21 PM

football said:

Hello! I love watching football and I loved your blog as well.

# May 22, 2011 8:24 AM

rtqfz said:

pzuctskdknr pa mapp

# June 20, 2011 2:01 PM

เพลงใหม่ said:

Thanks a lot, This article is very good I still remember when I was training a new asp fun in my asp has been very popular.

# July 9, 2011 6:35 AM

Pefhoonvelo said:

I just book marked your blog on Digg and StumbleUpon.I enjoy reading your commentaries.

# July 12, 2011 3:22 AM