Skip navigation

Category Archives: Programming WPF

To some it may appear that I have abandoned client side development for Azure. Nothing could be further from the truth. As I’ll tell anyone who will listen, I’m just like a kid who’s opened his presents on Christmas and found a new toy to play with. After playing with the new toy for a while, eventually I’ll remember my old favorite and start playing with it again. (The real fun comes of course when I start playing with both together). It’s not a Buzz Lightyear vs. Woody…it’s more like Megatron vs. Galvatron. Anyway, I had to come back to Megatron at some point or another. And a recent thread within the WPF Disciples mailing list gave me that impetus. I’ve recently realized how effective refactoring can be for getting working code out rapidly while still addressing maintainability. My experiments with refactoring resulted in a technique I like to call "context sensitive architecture."

A Practical Application

I’m not a huge fan of contrived applications, but sometimes we do what we must. This won’t be one of those times. Let’s say you have an application that could provide a rich view of your digital life and how that digital life is connected. Let’s say for now the application could show contacts and bookmarks. Finally, lets say that the application wants to allow the user to add and edit contacts and bookmarks. How do you enable these scenarios? One way would be to create a CreateContactControl, an EditContactControl, a CreateBookmarkControl, and an EditBookmarkControl. I guess we want to allow the user to View their contacts and bookmarks. Now we have to add a ViewContactControl and a ViewBookmarkControl. What happens when we add RSS Feeds and Podcasts to the mix? Now we have to create six more controls and integrate them into the system. What’s worse is that the main app has to know about each and every control in order to display them at the appropriate time. Of course we could use plug-in model to alleviate some of this pressure, but this could end up generalizing your application to the point where it is little more than a shell. There’s nothing necessarily wrong with that, but I still think there’s a compromise between the two extremes. Sometimes that compromise isn’t very obvious. Hence, we use refactoring and iterative development to discover the compromise.

The First Iteration

The first iteration of a project should be used to implement what is called a "vertical slice" or two. This will allow us to realize the benefits of Agile development with the first delivery. Getting working software into the customer’s hands quickly provides a compelling argument in favor of Agile development. I would actually recommend that you start with a minimal core team (2-3 members) for the first few iterations, this will enable you to minimize the overhead due to collaboration as the team takes its first steps into a new domain. It will also allow a few patterns to emerge before ramping up the velocity. Because you’re targeting a smaller amount of functionality for the iteration, you might want to do a shorter iteration. I think two weeks should be adequate.

Before we go any further, let’s try to visualize this app with a pair of its scenarios: "Add a Contact" and "Add a Bookmark". The "Add a Contact" story is very simple: "As a user of the application, I want to be able to enter information about a contact for later retrieval and viewing: his or her first and last name, and email address." Likewise the "Add a Bookmark" story is equally simple: "As a user of the application, I want to be able to store information about a bookmark for later retrieval and viewing: the URL, and title of the bookmark."

Based on these stories, we have identified two entities for our domain model: Bookmark and Contact. Here is the Bookmark:

   1:  using System;
   2:   
   3:  namespace Flow.Model
   4:  {
   5:      public class Bookmark
   6:      {
   7:          public Uri Address { get; set; }
   8:          public String Title { get; set; }
   9:      }
  10:  }

The Bookmark is very simple, consisting of a Uri and a Title. We will probably identify more information that would be interesting to capture for a bookmark in a later iteration. For now, we want to get working code into the hands of our stakeholders as quickly as possible. Our second object of interest is the contact:

   1:  using System;
   2:   
   3:  namespace Flow.Model
   4:  {
   5:      public class Contact
   6:      {
   7:          public String FirstName { get; set; }
   8:          public String LastName { get; set; }
   9:          public String EmailAddress { get; set; }
  10:      }
  11:  }

Let’s make a pair of controls for creating new bookmarks and contacts. Following the WPF developer – designer workflow, I will make the first pass on the UI simplistic and straightforward (relying on my designer to beautify it later).

After a few minutes in Blend, followed by some cleanup in Cider, I came up with a rather straightforward, minimalistic UI with the primary elements defined for optional elaboration by my designer:

image

image

Now that I have a way to create contacts and bookmarks. I should allow the user to view them. That’s easy enough. Let’s make a ListBox that shows the collection of contacts and another pair of controls that are read only. Rather than worrying about persistence at this point we’ll just store the information in memory.

So What Next?

We’ve delivered some basic functionality to our customers. More importantly, we have started the first path in our journey together. I will be placing the code on Codeplex. In addition I will be posting a screencast of me writing this code (once I figure how to get Camtasia to co-operate with me). This is something I’ve wanted to do for quite a while now. I just couldn’t find a project that I was compelling enough that would be able to grow from a very simple solution to a very interesting WPF application. I will reveal more about it over the upcoming weeks; in the process documenting the evolution what I feel is a very interesting application. Tune in for more info.

Advertisements

Or "My New Favorite Feature of the WPF Designer"

So I’m giving a quick presentation of my favorite new feature in VS 2008 at the Wisconsin .NET User Group Installfest, and because I hadn’t actually prepared for the presentation in advance, Murphy’s Law is in full effect. My normally snappy computer is crawling through the simplest of tasks (because I’m on battery power save mode). I’m floundering here and want to hurry and finish the demonstration (the "Cider" WPF designer). So now I’m standing in a pool of my sweat, I can’t even see because the saline is dripping into my eyes. And I have to remember the syntax for importing a CLR namespace. I look to a familiar face "Quick what’s the syntax for importing an assembly for reference in XAML?" Travis looks back at me with a blank stare. So I start typing hoping that something will pop in my head when I see:

image

At that very moment, I felt that Team Cider had put this feature in there for this very situation. I stated emphatically…well there you have my new favorite feature!

Overall the meeting was great. The turnout was HUGE. We had an assembly hall filled with people ready to install VS2008 (Professional this time as opposed to the 2005 launch when they gave out Standard). I forgot my full camera and for some reason, I can’t email the pictures from my phone so I’ll refer you to Larry Clarkin.

Hands down the best mini demo in my eyes was the demonstration of the code metrics capabilities of the VS 2008 Team Editions, the presenter of that feature won a copy of SceneIT! for the Xbox 360. Brennan won an 8 GB Zune for his presentation. There were a ton of toys donated in exchange for a raffle ticket. The winner got an Xbox 360 Elite with Halo 3 Limited Edition (not Legendary). And the food spread was fantastic. Especially the nacho toppings…chili and queso dip poured over tortillas is delicious! Overall, it looks like everyone enjoyed themselves. At the very least they got a free copy of VS 2008 Pro.

From Scott Guthrie’s announcement:

WPF UI Framework: The current Silverlight Alpha release only includes basic controls support and a managed API for UI drawing.  The next public Silverlight preview will add support for the higher level features of the WPF UI framework.  These include: the extensible control framework model, layout manager support, two-way data-binding support, and control template and skinning support.  The WPF UI Framework features in Silverlight will be a compatible subset of the WPF UI Framework features in last week’s .NET Framework 3.5 release.

I figured that Silverlight would get better by the time of release, so this doesn’t surprise me much. But I see more bullet points that attract my eye. Reading further:

Rich Controls: Silverlight will deliver a rich set of controls that make building Rich Internet Applications much easier.  The next Silverlight preview release will add support for core form controls (textbox, checkbox, radiobutton, etc), built-in layout management controls (StackPanel, Grid, etc), common functionality controls (TabControl, Slider, ScrollViewer, ProgressBar, etc) and data manipulation controls (DataGrid, etc).

I’ll refrain from sullying your screen with the filth that spewed out of my mouth when I read this (ESPECIALLY the bit about the built in DataGrid); but it was pretty much a recreation of the scene in Boondock Saints when Roc discovered that the McManus brothers had killed a room full of Russian Mafiosi (just discovered that word is the plural of Mafioso thanks to Live Writer). Back on subject, this is nothing short of amazing news! Let’s not forget the fact that this release will run on Macs and Linux. Add in the networking APIs and BCL support (including LINQ) and you have a compelling development platform. Excluding the WPF 3D library, Silverlight 2.0 will essentially live up to the original Silverlight codename and be WPF Everywhere.

Oh here was the killer! Silverlight 2.0 will go into Beta soon with Go Live license!

Scott’s post has some stuff in there about ASP.NET and Ajax and stuff…but I wasn’t really listening to all that. It sounds good and all but not half as thrilling as the Silverlight news. Adobe who?

I haven’t posted about this yet in my blog because I assumed everyone involved with WPF development already knew about it. IdentityMine is creating a set of utilities for WPF called Blendables. Basically, the focus of Blendables is to provide additional functionality for WPF that is accessible through XAML. One cool example is the Drag-and-drop implemented through an attached property. (Looks like someone finally took my advice on using attached properties to extend functionality).

Blendables is very similar to what my initial vision of the WPF Toolbelt. A library that exposes more of the WPF framework directly to XAML with minimum code-behind.  It’s great to see the third party support really taking off for WPF.

While you’re at the Blendables website, they are having a contest for people to showcase what Blendables has allowed them to do. Top prize is a 360 Elite. I won’t have time to submit a proper entry…I’m busy with other things.

Not to be topped by the incredible vista desktop in Silverlight, a new software shop has released a set of tools that apparently reproduce a vast number of Winforms controls in Silverlight. It’s somewhat hard to explain so just look at this. Note in particular the friggin’ WINFORMS DESIGNER clone. Again…WOW! By the way, their tool also supports flash and has a free edition (that’s missing some "advanced" controls…like a data grid), and a Professional Edition.

Definitely a way to increase your beta radiation levels.

If you remember, I spoke a bit about providing a rich designer for Business Analysts to define the flow of an application. It looks like Acropolis will go a long way toward realizing that dream. If you look at Glenn Block’s synopsis, you’ll see that it basically describes what I was talking about to a tee. Now I know why Rob’s only comment about the Domain Tree concept was "very interesting". He knew what was coming.

I for one am excited!

If anyone has tried loading a large number of items into a ComboBox…you’ve probably run into a long pause as the ComboBox renders an Element for each……and…..every….object….in….your….itemssource. You might have even resorted to using a ListBox instead even though it doesn’t quite fit in your UI.

Fear not my fellow WPF’ers because I have found the solution to your pain. ComboBox derives from ItemsControl and as such, has a ItemsPanel property of type ItemsPanelTemplate.

<ItemsPanelTemplate x:Key="Template_ComboPanel">

   <VirtualizingStackPanel IsVirtualizing="True"/>

</ItemsPanelTemplate>

If you set the ItemsPanelTemplate to use a VirtualizingStackPanel, the ComboBox will virtualize and you will have a much more responsive ComboBox. Even better, setup a Style for all ComboBoxes in your app and set the ItemsPanel to be that IPT. You’ll be a much happier camper. My Combobox holding 5000 objects used to take around 5-10 seconds to show the popup. Now it pops up instantly. 

So I am acutely aware that there is some confusion in the world about just what MVC is. I thought the paradigm I have been using for WPF would be considered MVC but after further research, I learned that while it is technically MVC, it is not what will first come to mind when you hear MVC. What I have been doing is making the View totally dumb. The only "knowledge" it has of the Model is imparted to it through databindings against properties exposed to it through my Controller. With "Pure" MVC, the View has a knowledge of the Model and can even act on it directly in some cases.

Doing a little more digging, I thought that I had found a name to the design pattern I have been using: Passive View. Martin Fowler’s definition of the Passive View definitely fits the bill for what I do:

A screen and components with all application specific behavior extracted into a controller so that the widgets have their state controlled entirely by controller.

Martin’s description of the passive view says that it’s primary benefit is that it makes your application more testable. I definitely have seen that benefit. I also have noticed that my code is more flexible to change when using this design.

However, I must point out that my Controller doesn’t actively update the view. It exposes properties that the View binds against. I also couple my MVC with the Command pattern (WPF really lends itself to the Command pattern seeing that it has the ICommand interface and certain UI elements have Command properties on them). All of my Controllers have a command that they expose for binding by the View, you could implement INotifyPropertyChanged, but I have been using Dependency Properties to handle all of those nuances.

Here is an example of how I would code a UI to all a user to search for an order in a customer service application. First we have the command OrderSearch (it might be an extension to a base Search Command or it might be the rSearch command with a Parameter SearchRequest that has an SearchType property (either way there will be an SearchRequest parameter). In this instance, my controller would also expose properties such as AvailableSearchFields, SelectedSearchField, SelectedSearchValue, and Results.

The View (in this case a UserControl subclass) would have its DataContext set to an instance of the Controller. There would be a ComboBox with its ItemsSource="{Binding AvailableSearchFields}" and SelectedItem="{Binding SelectedSearchField}". There is also a TextBox with its Text="{Binding SelectedSearchValue}" and a Button Command="{Binding Command}".

The only code behind required is the constructor which creates the controller and sets the control’s datacontext to the controller. (And that’s actually handled in the base class of the UserControl).

As you can see, there is NO logic in the UserControl, it only binds to (or observes) the Controller. Also, the Controller has no logic that deals with the UserControl directly…it only exposes properties, and performs logic in response to values being set.

The more I think about this pattern, the less it seems that it exactly matches Passive View, because Passive View implies that the Controller actually performs actions on the View. Again, my controller has no knowledge whatsoever of the view. It is not "Pure" MVC either because the View has no knowledge of the Model…I think this does follow the pattern that Dan Crevier described with Model – View – ViewModel. After going back and reading his blog further, this is exactly what this pattern is. I must have subconciously followed it. Anyway, I guess that this is just confirmation that it is definitely a pattern that works.

Using this pattern, my code is orders of magnitude more flexible and testable than using the code behind to drive the UI. I would also argue that it lends itself toward an SOA approach because of the Commands that are used to drive actions. In theory the same controller could be used to expose functionality to a website or to a Winforms UI. In order to do that, we’d probably want to move away from using DependencyProperties and instead implement INotifyPropertyChanged. Also we’d want to move from the WPF specific Command and create a Converter from our custom Command to WPF’s ICommand.

While I was putting my thoughts together on this posting, Paul Stovell again one upped me and posted his thoughts on "Binding Oriented Programming". He is more or less following the same pattern I use for WPF development.

Technorati tags: , ,

A while ago, I participated in a discussion in the forums about creating a webcam solution in WPF. My suggestion was to use the BitmapSource API to update a bitmap source dependency property with the buffer from a custom directshow filter.
 
The problem with that solution is that it involves a buffer copy rather than just updating a reference to point to the new buffer. A relatively new voice in the WPF Forums, Jeremiah Morrill, took the time to learn the WIC enough to get the raw buffer pointer in a BitmapSource and redirect it to look at another buffer. Here’s his blog about it.

Here’s the code, read on for the explanation.

So hopefully my last series on enabling MultiSelect checkboxes with attached properties reinforced the idea that the WPF team has been trying to bring home: subclassing a control should be used in extreme circumstances, because most enhancements can be done using Styles, Templates, and as I just showed Attached Properties. Here’s yet another trick that we’re using in a custom project.

For some reason the ATC team didn’t provide an IsSortable property on the GridView…all though they did show how simple it is to add sorting to a gridview using code behind. Well you know me, I like simple. So I created an Attached Property that uses the Plover Remora Pattern to add sorting to a ListView (with a Gridview as its View) without any code-behind (other than the code that’s in the attached property). The final XAML to use this functionality is as simple as this:

<ListView
  Util:WPFUtils.IsGridSortable="True"
  Width="Auto"
  Height="Auto"
  ItemsSource="{Binding MyItems}"
  SelectionMode="Multiple"
  Margin="5">
    <ListView.View>
      <GridView>
         <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}"/>
         <GridViewColumn Header="Department" DisplayMemberBinding="{Binding Department}"/>

         <GridViewColumn Header="Extension" DisplayMemberBinding="{Binding Extension}"/>
      </GridView>
    </ListView.View>
</ListView>

Basically all you have to do to make your GridView sortable is set the attached property IsGridSortable to true and it handles the rest. Since we already know how the Remora property works (an attached property adds functionality to the Control it’s attached to during the PropertyChangedCallback) We’ll cut straight to the code for our PropertyChangedCallback. (Full code will be available at the end of this posting).

private static void OnRegisterSortableGrid(DependencyObject sender,
  DependencyPropertyChangedEventArgs args)
{
  ListView grid = sender as ListView;
  if (grid != null)
  {
    RegisterSortableGridView(grid, args);
  }
}

private static void RegisterSortableGridView(ListView grid,
  DependencyPropertyChangedEventArgs args)
{
  if (args.NewValue is Boolean && (Boolean)args.NewValue)
  {
    grid.AddHandler(GridViewColumnHeader.ClickEvent, GridViewColumnHeaderClickHandler);
  }
  else
  {
    grid.RemoveHandler(GridViewColumnHeader.ClickEvent, GridViewColumnHeaderClickHandler);
  }
}

The callback basically checks if the property has been set on a listview (I am of course adding a check for if it’s set on a PowerGrid) and if so calls the RegisterSortableGridView function. This function adds a custom handler for the GridViewColumnHeader.Click Event or removes it based on the value assigned to the property by the user. The handler works pretty much the same way as the ATC sample with a few differences.

if (header != null)
{
  ListSortDirection sortDirection;
  GridViewColumnHeader tmpHeader = GetLastSorted(lv);
  if (tmpHeader != null)
    tmpHeader.Column.HeaderTemplate = null;
  if (header != tmpHeader)
    sortDirection = ListSortDirection.Ascending;
  else
  {
    ListSortDirection tmpDirection = GetLastSortDirection(lv);
    if (tmpDirection == ListSortDirection.Ascending)
      sortDirection = ListSortDirection.Descending;
    else
     
sortDirection = ListSortDirection.Ascending;
}

You’ll see I highlighted calls to two functions GetLastSorted(lv); and GetLastSortDirection(lv). These are Getters for Read-only Attached Dependency Properties LastSorted and LastSortDirection, respectively (and the SDK said they aren’t useful), that are set on the ListView during a sort operation…if this is the first sort operation of course they’ll be null. The other cool feature…

switch (sortDirection)
{
  case ListSortDirection.Ascending: resourceTemplateName = "HeaderTemplateSortAsc"; break;
  case ListSortDirection.Descending: resourceTemplateName = "HeaderTemplateSortDesc"; break;
}
DataTemplate tmpTemplate = lv.TryFindResource(resourceTemplateName) as DataTemplate;
if (tmpTemplate != null)
{
  header.Column.HeaderTemplate = tmpTemplate;
}

If the user has declared HeaderTemplateSortAsc and/or HeaderTemplateSortDesc in their resource tree, it will be set on the GridViewColumnHeader. Today’s upload only includes the cs file for the WPFUtils class. I’ll pull it out of our main app and into it’s own project later.

Again, this shows that WPF Controls can be customized without subclassing them. And without codebehind for the UI of the code cluttering your business logic code. Next time, I want to talk about MVC with WPF.