Syndicate

News

My name's Marco De Sanctis and I'm an IT professional from Italy. This is my technical blog, about .NET and related application development and design technologies.

Download my Resume (.doc)

Recent Comments

10/23/2008 at 3:48 PM

sorry, my previous post was not complete... I trie...
by glondi

Read more...

9/22/2008 at 10:03 AM

Good one!!!Could you please post source code for t...
by Nisa

Read more...

9/10/2008 at 5:53 PM

I didn't even realize people were aware of the WPF...
by Mike Brown

Read more...

9/8/2008 at 1:22 AM

Marco,How are you handling scenarios where you nee...
by ctodd

Read more...

9/3/2008 at 1:00 AM

@ctodd: Hi,basically for the reasons I described a...
by Marco De Sanctis

Read more...

Recent Posts

Crunch mode is a pure waste of time, energy and money

7/31/2008 at 5:41 PM

Read more...

Double Click on the .sln file doesn't open Visual Studio on Vista

7/27/2008 at 9:02 AM

Read more...

Domain Model & Aggregates: when do master-detail associations happen?

7/22/2008 at 4:08 PM

Read more...

How I Got Started in Software Development

7/14/2008 at 12:16 AM

Read more...

Unleash the power of VisualStateManager with custom states

6/30/2008 at 12:12 AM

Read more...

WPF best practices: decoupling behavior from the view

posted on Friday, May 09, 2008 6:28 PM | Filed Under [ WPF ]

One of the most interesting concepts in WPF is that a control's logic is completely decoupled from its layout: a button is something that reacts when user clicks it raising a Click event, despite of how it looks like. If you think about it, it's definitely a breaking change compared to Windows Forms, and it allows designers to completely reskin UIs, while keeping the behavior intact.

When you create a new custom control, Visual Studio adds two files to your solution:

  • a C# (or VB.NET) file, which is supposed to hold all your control behavior logic
  • a Generic.xaml file, which provides a default control template for its layout.

The Generic.xaml file contains various child UI elements that need to interact with each other and with the underlying behavior logic, and this has to be done without introducing dependencies from the logic to the UI. In my experience building custom WPF control, I've been able to achieve that following three main rules:

  • Triggers (and eventually Binding between UI elements) to encapsulate layout-only logic within XAML
  • Handle data flows (both One-Way and Two-Way) from UI to control logic with Binding
  • React to UI's events using Commands

While the first two points are pretty straightforward, the third deserves a small overview. Let's suppose we're building an "File selector" custom control, similar to the following:

image

The behavior needs to be notified when the user clicks the Browse button to display the standard Windows Open File Dialog. Obviously we could assign the button a unique name

image 

and attach its click event in C# code:

image

That kind of implementation has a couple of serious drawbacks:

  • It works until there's a button named browseButton somewhere in the control template. If a designer reskins our control and doesn't provide a button with that exact name, or if he wants to use some other event, or even a different control type that doesn't inherit from button, our logic stops working correctly;
  • Our logic is so tightly bounded to the UI that we can have one and only one control triggering the opening of our open file dialog.

WPF's Commands infrastructure offer a much more elegant (and simple) solution to all those issues. A Command is the object oriented alter-ego of a functional logic, that can be enabled or disabled, triggered by an input gesture and associated to some code, regardless of what and how many UI elements are bound to it.

So, our first step is to create a proper command, stored in a static readonly field initialized into the control's static constructor. A command is a class that implements the ICommand interface; WPF has several built-in commands for the most common tasks (Cut, Copy, Past, and so on... here there's an exhaustive list). In our case, we can use the already existing RoutedCommand class:

image

Two main details to notice:

  • After building the BrowseFileCommand, you need to bind its Executed event to a proper event handler and register that binding to the CommandManager;
  • The event handler is static, but you can retrieve a reference to the current BrowseFile instance looking at the e.Source property;
  • There's absolutely no reference to any UI element in the code we've just written.

What about the general.xaml file? All we need to do is associating the BrowseFileCommand to the button object with its Command property:

image

Now, our BrowseFile behavior is well encapsulated within the C# class and its BrowseFileCommand custom command; a designer who wants to completely re-invent our control's layout only needs to attach it to the UI elements he prefers; Notice also how easy was to include a context menu with the same behavior, simply reusing the same command.

In a next post, I'll show you how to build a completly skinnable and bindable custom control from scratch.

Cheers.

kick it on DotNetKicks.com

Technorati Tags: ,,

Comments

Gravatar
# re: WPF best practices: decoupling behavior from the view
Posted by alkampfer on 5/9/2008 6:40 PM
Very interesting sample, I'm really amazed of the possibilities of WPF.
Gravatar
# re: WPF best practices: decoupling behavior from the view
Posted by Roy on 6/26/2008 12:21 AM
I really hope you could help me out on this. Say I have a DependencyProperty named ActiveItem. How do I programmatically change the value of ActiveItem and UPDATE the databound ComboBox or any other Selector? Also please note that the ActiveItem is updatable via the Selector UI.
Gravatar
# Composite Application Guidance
Posted by Ben Ellis on 9/2/2008 11:12 AM
If you want to take this one step further, check out the Composite Application Guidance for WPF from the Patterns & Practices develop center on MSDN.

You probably don't need to be so decoupled unless you're writing an Enterprise Application. But an interesting read never the less.

http://www.microsoft.com/downloads/details.aspx?FamilyId=6DD3D0C1-D5B4-453B-B827-98E162E1BD8D&displaylang=en
Gravatar
# Online pharmacy cost levitra.
Posted by Buy sublingual levitra online. on 5/31/2009 10:17 AM
Levitra for pe. Levitra side effects. How long does levitra last. Levitra.
Gravatar
# Levitra dangers.
Posted by Buy viagra online uk cialis levitra. on 6/1/2009 3:29 AM
Generic levitra. Cialis and levitra. Levitra. Using levitra for eczema..
Gravatar
# Tramadol.
Posted by Lowest price tramadol. on 6/2/2009 4:31 AM
Comparative potencies of opioids tramadol. Buy tramadol. Will tramadol hcl test positive in drug testing. Tramadol ultram medicine. Tramadol side effects. Tramadol. Side effects tramadol.
Gravatar
# Propecia.
Posted by Does propecia thin hair out at first. on 6/3/2009 9:27 AM
Fertility and propecia. Natural herb reverse impotence from propecia.
Gravatar
# Cialis.
Posted by Taking cialis. on 6/3/2009 3:13 PM
Buy cialis. Cialis.
Gravatar
# Levitra.
Posted by Levitra. on 6/3/2009 5:20 PM
Buy sublingual levitra online. Levitra voucher. Levitra attorneys. Levitra. Which is more effective viagra cialas levitra.
Comments have been closed on this topic.