Featured Posts

WPF and the Event Routing Paradigm, with Bacon Since the first event-driven language came down from the mountain and became part of the software development vernacular, there has been a certain notion of how an event works. Subscribe...

Read more

How to stop Expression Blend 4 RC from crashing on... So you’ve downloaded Expression Blend 4 RC but when you start it up, Blend crashes hard.  It’s never done that before, right? What do you do?  Well, you can...

Read more

The WPF Must-Grok List Robert A. Heinlein defined the word grok as: Grok means to understand so thoroughly that the observer becomes a part of the observed—to merge, blend, intermarry, lose identity...

Read more

Yes, Virginia, TextBlock.Text Will Support MultiBinding One of the features introduced to WPF in version 3.5 SP1 is the StringFormat property. If you’re unaware, StringFormat allows you to bring the String.Format capability...

Read more

Why Are WPF Developers Trying to Kill Menus? Somewhere along the line, and I’m not motivated enough to research it, menus apparently became bad.  I don’t mean they ever stopped working or became unsuitable for the...

Read more

using System.Windows; Rss

WPF and the Event Routing Paradigm, with Bacon

Posted on : 24-05-2010 | By : Christopher Estep | In : Basics

Tags:

1

Since the first event-driven language came down from the mountain and became part of the software development vernacular, there has been a certain notion of how an event works.

Subscribe to Event Subscribe to event
Fire that event! Event fires
Event Handling in Forms is easy, but messy Deal with event
Direct Event Goodness! Breakfast!

All in all, it’s pretty simple.  And life was good.

So along comes WPF and things start to get a little more complicated. Events no longer have a simple one-to-one relationship. The event cycle may not be what you expect.

Event Subscription Subscribe to event
Fire that event! Event fires
Events bubble and multiply Events everywhere!
Event Handling doesn't have to be messy Deal with event
Runaway Events Events still running away!

As I said, it’s not quite what you expect. Previous to WPF, event handling was very direct and closed. An event went where it was told and that was that. With WPF, events have a mind of their own, or so it would seem.  But once you begin to understand what happens and why, WPF’s event-handling paradigm begins to make a lot more sense. And this paradigm is called Routed Events.

Manual versus Automatic

Windows Forms style event-handling is very manual. You subscribe to an event, deal with the event and it’s over, whether you like it or not. On one level, it means there are less pieces to worry about, less things that could go wrong. But the more you work with that style of event-handling, you realize how much your handcuffed by it.

To demonstrate the Windows Forms or CLR approach, I’ve made a Forms application to demonstrate how event processing occurred previously (and still does in non-WPF & non-Silverlight applications)

RoutedEventWinForm-1

And the following code-behind:

public partial class Form1 : Form

{

    public Form1()

    {

        InitializeComponent();

        button1.GotFocus += new EventHandler(button1_GotFocus);

        button2.GotFocus += new EventHandler(button2_GotFocus);

        tabControl1.GotFocus += new EventHandler(tabControl1_GotFocus);

    }

    void tabControl1_GotFocus(object sender, EventArgs e)

    {

        textBox1.Text += String.Format("tabControl1 GotFocus{0}", Environment.NewLine);

    }

    void button2_GotFocus(object sender, EventArgs e)

    {

        textBox1.Text += String.Format("Button2 GotFocus{0}", Environment.NewLine);

    }

    void button1_GotFocus(object sender, EventArgs e)

    {

        textBox1.Text += String.Format("Button1 GotFocus{0}",Environment.NewLine);

    }

}

Pretty simple.  When you it, you get:

RoutedEventWinForm-2

All I did was tab through the controls and it printed exactly one line each time.

This is because normal events are “one and done” in the sense that once they are dealt with, they are considered to be handled and it’s all over.

Now let’s take a look what happens in WPF.  I made a simple form in WPF (if anything in WPF can be considered simple, but this one actually is) and wired the GotFocus event for each of the controls, but I also wired it up for the form itself.

RoutedEventWPF-1

The XAML:

<Window x:Class="WPFEventDemo.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        Title="MainWindow" Height="350" Width="525" GotFocus="Window_GotFocus">

    <Canvas>

        <TabControl Canvas.Left="80" Canvas.Top="46" Height="100" Name="tabControl1" Width="200" GotFocus="tabControl1_GotFocus">

            <TabItem Header="tabItem1" Name="tabItem1" GotFocus="tabItem1_GotFocus">

                <Grid GotFocus="Grid_GotFocus">

                    <Button Content="Button1" Height="23" HorizontalAlignment="Left" Margin="20,11,0,0" Name="button1" VerticalAlignment="Top" Width="75" GotFocus="button1_GotFocus" />

                    <Button Content="Button2" Height="23" HorizontalAlignment="Left" Margin="20,39,0,0" Name="button2" VerticalAlignment="Top" Width="75" GotFocus="button2_GotFocus" />

                </Grid>

            </TabItem>

            <TabItem Header="tabItem2" Name="tabItem2">

                <Grid />

            </TabItem>

        </TabControl>

        <ScrollViewer Height="116" Canvas.Left="28" Canvas.Top="172">

            <TextBlock  Name="tb" Text="" Width="446" />

        </ScrollViewer>

    </Canvas>

</Window>

And the code-behind:

public partial class MainWindow : Window

{

    public MainWindow()

    {

        InitializeComponent();

    }

    private void button1_GotFocus(object sender, RoutedEventArgs e)

    {

        tb.Text += String.Format("Button1 GotFocus \n");

    }

    private void button2_GotFocus(object sender, RoutedEventArgs e)

    {

        tb.Text += String.Format("Button2 GotFocus \n");

    }

    private void Grid_GotFocus(object sender, RoutedEventArgs e)

    {

        tb.Text += String.Format("Tab 1 Grid GotFocus \n");

    }

    private void tabItem1_GotFocus(object sender, RoutedEventArgs e)

    {

        tb.Text += String.Format("tabItem1 GotFocus \n");

    }

    private void tabControl1_GotFocus(object sender, RoutedEventArgs e)

    {

        tb.Text += String.Format("tabControl1 GotFocus \n");

    }

    private void Window_GotFocus(object sender, RoutedEventArgs e)

    {

        tb.Text += String.Format("----------------------------\n");

    }

}

And when you run it you get:

RoutedEventWPF-2

with the following in the TextBlock:

tabItem1 GotFocus

tabControl1 GotFocus

—————————-

Button1 GotFocus

Tab 1 Grid GotFocus

tabItem1 GotFocus

tabControl1 GotFocus

—————————-

Button2 GotFocus

Tab 1 Grid GotFocus

tabItem1 GotFocus

tabControl1 GotFocus

—————————-

Each section is the result of a single press of the tab key, including the dashed line. What you’re seeing is the result of event bubbling and this happens every time an event is fired in WPF and Silverlight.  Look at the second group. When I tabbed to the button, it fired GotFocus for the deepest, nested object and then bubbled up doing likewise to each object in the tree until there were no more left. In fact, the GotFocus event for MainWindow is what added the dashed line at the end.

But what if you don’t want that behavior?  That’s simple enough. You may have noticed that I haven’t been using the term “handle” for dealing with events. This was intentional, because “handled” has a specific meaning in RoutedEvent processing and now you’re going to learn what.

If you don’t want events to bubble up past a certain point, all you need to do is set Handled=true for RoutedEventArgs in the handler. At that point the bubbling stops and WPF truly considers the event completely handled. What is key is that I said “past a certain point”. You can stop the bubbling anywhere in the hierarchy, not just at the control that caused the event.

In the following code, I’ve set Handled to true at Button1 and tabItem1.  Watch what happens.

RoutedEventWPF-3

Again, I tabbed 3 times. The first tab gave focus to tabItem1 and since I set Handled to true in tabItem1, that’s all it printed. The second tab went to Button1 and since Handled is true in that method, it also just prints one line. But I didn’t set anything in Button2 so when I tabbed to that control, it ran the handlers for Button1, the unnamed grid that is it’s parent and tabItem1, again stopping.

It’s important to note that if I had clicked tabItem2, it would have printed “tabControl1 GotFocus” and a dashed line because I never removed those handlers.

Conditional handling

I put the following code in the the tabControl1 GotFocus handler method:

private void tabControl1_GotFocus(object sender, RoutedEventArgs e)

{

    Control osControl = e.Source as Control;

    if (osControl.Name == "button1" || osControl.Name == "tabItem2")

    {

        e.Handled = true;

    }

}

And what you’ve got is a very simple way of conditionally deciding if you want the event to keep bubbling all the way up the tree.

I hope I’ve given you enough information so that in your own events processing you can turn this…

Runaway Events!

into this…

Event Handling Tastes Like Bacon!

(ALTERNATE VERSION for vegetarians)

I hope I’ve given you enough information so that in your own events processing you can turn this…

Evil Carrot

into this…

Event Salad!

[Side note: Yes, I know I only talked about Bubbling and WPF also supports Tunneling.  I’ll cover Tunneling in a future post!]

[Side note 2: Yes, I also know that Routed Events are not a new subject in the WPF and Silverlight world, but I was asked about them and it's never a bad time to go over the fundamentals.]

kick it on DotNetKicks.com

Popularity: 30%

Absent from my Grok List

Posted on : 11-02-2010 | By : Christopher Estep | In : Basics

2

It’s been suggested that my WPF Must-Grok List is “basically the whole WPF” so in my own defense, I thought I’d list a few items to illustrate how WPF is far deeper than my list:

  1. Attached Properties
  2. Visual & Logical Trees
  3. MVVM
  4. Prism
  5. Click-once deployment
  6. Browser apps
  7. Animation
  8. Graphics (2D)
  9. 3D Graphics
  10. Flow Documents & Text
  11. Ink
  12. Printing & XPS
  13. Media
  14. Adorners
  15. Custom controls
  16. Interop

And even this is not a complete list.

Remember, WPF is a new paradigm in software UI development. It does have a significant learning curve and it is a huge mistake to oversimplify it.

Popularity: 26%

The WPF Must-Grok List

Posted on : 11-02-2010 | By : Christopher Estep | In : Basics

Tags: , ,

2

Robert A. Heinlein defined the word grok as:

Grok means to understand so thoroughly that the observer becomes a part of the observed—to merge, blend, intermarry, lose identity in group experience.

or in other words, to fully completely understand and internalize it.  It’s the difference between knowing something because you have read it and truly knowing how it works and why.  I would say that it’s the difference between intellect and application.

Man thinking in libraryjpg

As I’ve said before, WPF is in many ways a paradigm shift in software development, especially if you’re coming from the Windows Forms world.  As a result, there are a number of new (and/or different) concepts that you really have to grasp, or grok before you could ever consider yourself proficient.  I’ve been working with WPF for about 2 years now and there are still things that make me stop and think.  Having said that, I think the effort is certainly work making and the result of your hard work is software that is also worth making.

So for budding WPF developers, I give you a list (as opposed to a tutorial) of what I think are some of the most important concepts and methodologies that you really should master in order to get the the most out of WPF.

  1. Dependency Properties – It is impossible to be even remotely effective in WPF if you don’t understand them.  In many ways, dependency properties are the basic nerve system of WPF.  Very little functionality exists in WPF that doesn’t rely on them.
  2. XAML – If you don’t like it or are resistant, just suck it up and deal with it.  Seriously. XAML is not only used in WPF, but in Silverlight and WF as well.  Whether it’s XAML, HTML, or plain-old XML, the XML-based development methodologies are here to stay.
  3. Binding, binding, and more binding – I can’t even begin to stress how important it is to understand WPF data binding. You simply can’t develop with WPF without it and it takes more than a basic understanding to use it effectively.  You genuinely need to understand the hows and whys or else you’ll spend more time debugging your bindings than just about anything else.  Even if you actually do grok WPF data binding, you’ll still probably spend a significant slice of your debugging time fixing and diagnosing your bindings.
  4. Routed Events – WPF handles events differently than other technologies, introducing the concepts of “bubbling” and “tunneling” to event handling.  While you can still handle events the old way, you shouldn’t. Trust me on this one. Routed events will ultimately make your life easier than you can imagine, at least as far as event handling is concerned.
  5. Commands – Again, you can do things the “old way” but Commanding solves a number of problems, particularly aiding in the best practice of separation of concerns and encapsulation. The command pattern is somewhat different in WPF than what you may be used to, so it’s best not to assume that you know how it works already (with WPF) which is why it’s on this list.
  6. Layout, Measuring, and Arranging – WPF lays out controls and children using very specific rules and principles.  While a comprehensive understanding isn’t required unless you’re writing your own controls, you still need to get a handle on how measuring and arranging works and what is done during each phase. This will really help when WPF puts something where you aren’t expecting and you’ll know where to look for a solution.
  7. WPF Threading – Yes, I’m serious. If you’re like many programmers, you’ve avoided threading topics as being either too esoteric or more “bare metal” than you need to deal with. I get that. Business application developers have historically had no concern for threading because we typically deal with “fast enough” performance. WPF changes that, seriously.  It doesn’t change the practice of “fast enough” for business applications, but it rigidly requires all updates to UI objects be made from the UI thread. Again, I realize this isn’t a problem for the vast majority of programs. But I promise that at some point when you don’t have time to study a new topic, you’ll be using some asynchronous API and will try to make a change to a UI element from another thread and WPF simply will not let you. It will happen, I assure you. Asynchronous API’s are becoming the norm and unless your applications never interact with the outside world, you’ll be using one at some point.  It’s better to know what the Dispatcher is, how it works so you don’t have to take a crash course in WPF threading when you can least afford to spend the time to do so.
  8. Styles & Templates – Fortunately, WPF’s implementation of styles is pretty straight forward. But, like so much of WPF, it’s different than what you’re going to be used to and you absolutely must know how they work. Unlike most of CSS, WPF styles allow you to dramatically affect behavior as well as appearance and that’s why they’re so crucial. Templates (especially Data Templates) also affect behavior and appearance but in a different (though complementary) way. Both are integral to almost every WPF application.
  9. Triggers – While Microsoft includes them in with styles & templates, I think triggers deserve mention on their own.  Yes, it’s through triggers that styles and templates can manipulate your controls, they’re important enough to require study on their own. In my mind, triggers are like declarative event handlers that can be put pretty much anywhere without having to worry about the actual event handling plumbing itself. Triggers will also be the means by which you do any animation and a variety of other tasks.
  10. Resources – You must understand how resources work. I can’t say it any more simply than that.  Resources are such an integral part of WPF, you will use them in every single application you write and almost every single XAML file and much code as well. More than anything in WPF, resources tie your application together.

Obviously, this isn’t an all-encompassing list. There are certainly more topics that you need to know, not the least of which being the myriad of WPF controls, deployment, printing, and so forth.  But I can honestly say that without knowing and truly understanding the 10 concepts I’ve outlined above, you’re doing yourself, your customers, and (if applicable) your employer a grave disservice by not being the WPF expert you could be.

And don’t misunderstand me, either. Knowing these concepts only provide the foundation for so much more you’ll have to learn through experience. My grok-list is the beginning, not the end. But if you do grok these concepts and technologies, I promise you that you’re well on your way to being the expert you want to be.

Popularity: 100%

WPF: What it is and What it is not

Posted on : 05-10-2009 | By : Christopher Estep | In : Basics

Tags: , ,

1

Even though WPF has been around for a number of years, there is still some confusion as to what WPF is and what it is not.  Here are a few items that come to mind:

What WPF is

  • A replacement for Windows Forms.  If you’re going to be writing applications for the Windows desktop (as opposed to the web), you need to learn WPF.  Microsoft has spent a considerable amount of resources (both in time and money) making WPF their “go-to” solution for the desktop.  Don’t avoid learning WPF because you think it’s an ancillary technology.  It’s not.  For a desktop programmer to ignore WPF is akin to a web programmer ignoring ASP.NET.  Sure, you can do it, but it’s a decision to abandon most of Microsoft’s technology stack for that target platform.
  • A paradigm shift in programming.  I don’t know of any developer who has picked up WPF and said, “this isn’t so different” because the simple fact is that it’s not only different, it’s a complete change in how you approach user-interface development.  In many ways, it’s closer to web development than WinForms. This is partially due to XAML introducing declarative interface programming to the desktop, where previously your typical developer only saw it on the web or esoteric, domain specific environments.
  • The future. Like it or not, WPF is here to stay.  As I said previously, Microsoft is betting the store on Windows Presentation Framework.  Ok, maybe not the whole store, but after being “out there” for over 3 years, Microsoft is putting WPF on all of its new operating systems (including the new Windows 7) and even Visual Studio 2010 is written with WPF.
  • Stable. It’s to Microsoft’s credit that .NET 3.5 and .NET 4.0 didn’t bring significant changes to WPF.  There wasn’t a whole lot that needed changing, aside from largely internal core issues such as performance.  Further, there were virtually no breaking changes from version to version, especially when compared to the migration from .NET 1.0 –> 1.1 –> 2.0.
  • Robust. There is very little from a user experience (UX) perspective that WPF doesn’t make possible.  This even includes 3D, Animation, Surface, and in 4.0, multi-touch.
  • Hard. The best technologies are rarely easy and WPF is no exception.  You have to change the way you approach both UI design and development.  And you do have to change the way you think. It’s no exaggeration to say that WPF comes with a very steep learning curve.  Fortunately, once you get past the paradigm shifts and really begin to grok some of the fundamental concepts, your development time should drop dramatically and you will begin to see a good return on your investment in development time as well as the quality of your output.

What WPF is not

  • Cross-platform. WPF runs on Microsoft Windows only.  Is that limiting?  Not really.  If you exclude mobile devices, you still have about 94% of the operating systems/desktops and that’s certainly nothing to sneeze at.  Windows 7 releases soon and is getting wide praise (especially compared to Vista) and I expect that Windows’ market share will increase.  Also, WPF’s single-platform focus doesn’t place needless constraints on the technology the way Silverlight does.  With WPF, you don’t have to dumb-down your application for a very small minority.
  • Silverlight. The Silverlight/WPF argument is akin to the chicken/egg one.  The fact though is that WPF did come first.  They’re doing a great job at bringing much of the WPF functionality to Silverlight, which does give you an option if you need cross-platform functionality, but there are still quite a few things that WPF does better or simply does that Silverlight cannot do at all.  I’m going to do a post or two on those differences in the near future.
  • Slow. All things are relative.  Yes, compared to many WinForms apps, WPF could be considered slow.  But you know what?  Compared to console applications, GUI’s are slow.  Compared to straight HTML, Javascript is slow.  Compared to Javascript, server controls are slow (generally).  You’ll have to forgive my annoyance, but the “slow” arguments are the same ones I heard tossed at Excel by people who were still determined to use 1-2-3 and by Netware guys who didn’t like Microsoft and/or NT.  The fact is that most current desktops run WPF just fine when the application is well written and that’s always been the case.
  • Mobile. The only way to make WPF mobile (like cross-platform) is to compromise features.  This gets back to Silverlight which is a subset of WPF’s functionality.
  • A language. I know to some I’m being pedantic and nitpicky, but I’m really not.  You don’t write an application in WPF, you write it for WPF.  The distinction might seem minor on the “surface” (insert groan here), though it’s not.  I can write an application utilizing the WPF frame work in any number of languages, including C#, VB, F#, IronRuby, or any other language that can call the .NET stack.  Conversely, I can’t really write a WPF web application, service, or console app.  WPF is the technology, languages are the means of accessing that technology.
  • XAML. This one is for those who thought, “what about XAML?” when I said WPF isn’t a language.  Nope.  XAML is the language, again, the means of accessing the technology.  You don’t even need XAML to write a WPF app.  In fact, knowing how to do so is (in my opinion) an essential skill if you truly want to understand WPF.  Ironically, I believe that in order to really understand how XAML is used for WPF, you should know how to write WPF apps in procedural code.  There are books that can help you do just that and I’ll get to that in a few posts.
  • Going Away. I’ve been listening to so-called pundits sounding the death-knell of desktop apps for over a decade.  This is because people like Larry Ellison and anyone sitting in their mom’s basement pounding the refresh key on Slashdot have seen thin clients and now RIA as the key to taking Microsoft down.  There will always be a need for desktop applications, at least well-written ones.  When given the choice between a well-written desktop app (via WPF) and a well-written web application, my experience is that people will choose a desktop application every time, unless there’s a business reason that requires web functionality.  Even then, if you (the developer) know what you’re doing, most of that functionality can be done on WPF.

The Bottom Line

Hammer

There’s a great saying that says, “when all you have is a hammer, everything looks like a nail” and that’s how a lot of developers and consultants respond to business problems these days.  I can’t count the times I’ve heard times I’ve heard, “I bet I can make a web application that will do that.”  Well, I bet I can make a desktop application that runs as a storefront to amazon.com, too.  In fact, I know I can.  That doesn’t make it a good idea.

933587_98174214The problem is that there are a lot of very good web application programmers that are disproportionate to the number of very good desktop application programmers (or those with both skill sets), so a lot of these folks simply validate “web app everywhere” mentality by virtue of sheer numbers.  Think about it.  If you ask a room with 20 orthopedists and 2 chiropractors how to help a person’s back pain, what do you think the “prevailing wisdom” of the room is going to be?

The bottom line is that there is a huge need for quality desktop applications, but there’s an even greater need for developers and consultants who can identify those needs.  Otherwise, it’s hammer time and every requirement is one big fat nail just waiting to be nailed to the world wide web.

Popularity: 34%