Overview

This is part 3 in a series of demos to accompany an East Bay .Net User's Group project. While the User's Group project takes a "software-as-service" approach, our series will focus primarily on the presentation layer, applying WPF to a set of non-trivial interface requirements, while paying special attention to the need for clean, maintainable, extensible code. The project consists of an OrderEntry application, used to generate and track walk-in and phone-in customer orders, with a separate OrderMonitor application to display open pizza orders to the kitchen staff. We are NOT trying to suggest that this particular UI (or the use of WPF, for that matter), would represent an appropriate solution for a similar set of real-world business requirements, but it enables us to discuss many real-world project concerns while exercising a broad range of WPF features.
  • PizzaManiac 1 : Simplistic WPF layout to support basic application structure and behavior
  • PizzaManiac 2 : Realistic feature set, real-time WCF communications, and some UI customization
  • PizzaManiac 3 : Significant increase in complexity, to support multiple product types
  • PizzaManiac 4 : Robust communications and data management, .Net 3.5 updates, and a more polished UI

What's New?

The biggest change is a transition to a much more realistic level of complexity in the set of business requirements that our code and UI are expected to support. An order can now contain any number of drinks and desserts in addition to pizzas, displayed "Size" options vary, depending on the specific product type (a "pitcher" of beer, "carafe" of wine...), and pizzas support additional customization, requiring associated changes to the pricing structure.

To try to support these new requirements in an intuitive, visually concise way, we've added images to trigger the display of Add/Edit inset views matching each product category. Items in an order can be edited by double-clicking on them, but editing an active kitchen order will result in the cancellation and REPLACEMENT of the entire original order, until database support enables us to provide a more sophisticated solution.

verysmallOrderEntry.png verysmallOrderSummary.png

Animation should generally be used sparingly in real-world projects (and consist of something much more subtle than our "spinning" inset window), but we've included gratuitous animations in order to highlight some interesting implementation issues, including the topic of integrating Expression Blend into the development process.

FlyOut.png

"Custom" pizzas have been redefined to support a list of specific ingredients, all pizzas support "Thick Crust", "Deep Dish", and "Extra Cheese" options, as well as an option to forwared special instructions to the kitchen staff, like "Hold the olives".

verysmallCustomPizza.png verysmallComboPizza.png


Other product edit views currently don't contain alot of detail...

verysmallDrink.png verysmallDessert.png


Integrating the new pizza options into the kitchen order UI required minimal changes to the existing design.

verysmallOrderMonitor.png


User entries are validated against regular expressions pulled from an XML file.

verysmallCustomerValidation.png

Basic User's Guide

  • Launch "SimpleServiceHost.exe" in the _Output\Debug\ProcessingService directory
  • Launch OrderEntryUI.exe and OrderMonitorUI.exe (in other Debug sub-directories)
  • In the OrderEntry client, click the "Add New Order" button, add at least one pizza, and click "Save Changes"
  • To simulate that kitchen processing of the Pizza has finished, click on the Pizza in the OrderMonitor client, and click the round "X" button
  • To edit an existing order, or to assign delivery or mark an order completed, click on the order in the OrderEntry client.
  • Scheduled orders are started automatically, when the current time is within 30 minutes of the scheduled time for that order.
  • Changes to orders already in progress will cause the original order to be cancelled, and a new order to be started.

Implementation Notes

To support our new "Drink" and "Dessert" product types, shared "Price", "Type", and "Size" fields have been moved to an abstract "OrderItem" base class, enabling us to clone, add, delete, and get pricing information, without having to refer to specific product types, throughout most of the code base. The use of an abstract base class requires us to explicitly identify all derived types for any WCF operation involving the base reference (Overlooking this will cause the operation to fail silently).

[ServiceKnownType( typeof( Pizza ) )]
[ServiceKnownType( typeof( Drink ) )]
[ServiceKnownType( typeof( Dessert ) )]
[OperationContract( IsOneWay=true )]
void ProcessOrder( Order order );

The OrderEntry client submits the entire order for "processing", and our processing service will eventually store order data in a database., but currently just extracts and forwards pizza information to the kitchen.

We've made several significant changes to the project structure, moving service proxy references, service data extensions, and (XML file) data access code into separate assemblies, helping to manage growing complexity through stricter enforcement of separation of concerns. Our prefix-based file naming convention and nested UserControl UI architecture made it easy to identify elements that needed to be changed in the new design, and to carry out those changes, and the use of local EXTENSIONS to data contract classes made it possible to implement UI support for new features, like our pizza options, just by adding a few bindable properties.

Add/Edit view transitions are implemented by animating a CONTAINER of view instances, with only one view visible at any time. The animations involve a mix of Storyboard markup and code-behind, and require relative width settings of the image column to be restored, in order for images to continue to grow and shrink automatically whenever the application window is resized.

Animation and other visual effects can often really only effectively be designed using a tool like Expression Blend. Unfortunately, Blend's simple point-and-click interface tends to encourage casual generation of massive amounts of convoluted Xaml, which must be refactored early and often if you expect to have any hope of maintaining the project source over time. Members of the developer community, including some inside Microsoft, have discovered benefits in keeping Blend and Visual Studio project activity separate -- even to the point of manually cutting and pasting carefully refactored versions of Blend-generated Xaml into the "official" project source, rather than allowing designers and developers to operate directly on a single shared code base.

MS User Experience Team - lessons learned in teaming devs and designers on actual WPF projects
Billy Hollis demos a very nice UI, discussing design/dev. lessons learned on an actual WPF product


The workflow I followed, to generate animation sequences for this project, was to open the relevant subproject directly in Blend, implement the desired visual effect, and immediately switch to Visual Studio to refactor the generated Xaml by hand. For example...
  1. Open ClientUI\OrderEntryUI\OrderEntryUI.csproj in Blend
  2. Under the "Project" tab, double-click viewOrderDetails.xaml
  3. Navigate the object tree, and double-click EditItemViewContainer
  4. Create a new animation timeline, and interactively design your animation
  5. Use Visual Studio to cut and paste Xaml for the completed animation into the appropriate Storyboard in resAnimations.xaml, and refactor (adjusting timing precision, removing unecessary keyframes, etc.)

What's Next?

The next iteration of our project will rely on Windows Activation Service (WAS) to host our WCF services, eliminating the need to launch a host process manually, and an svcUtil build script to eliminate having to edit auto-generated service references on the client. An SQL Server Express database will store order, menu, pricing, employee, and other information.

smallDataAccessStrategy.png

The next version will also include updates related to the recently-released .Net 3.5 service pack, including GPU Accellerated Effects to replace deprecated Bitmap Effects.

We'll also fix a few corner case glitches, and try to add some more polish to the UI, which is currently a little too... blue?

Other projects by Andy L.



Last edited Oct 14, 2008 at 3:38 AM by AndyL2, version 63