Click here to Skip to main content
Click here to Skip to main content

Shopping - A .NET shopping application for Pocket PC

, 28 May 2004 CPOL
Rate this:
Please Sign up or sign in to vote.
Shopping is an application written in C# for the Pocket PC. It is a program which can be used to assist you in your daily shopping needs.

Introduction

As a software developer and a geek before all, I dream that paper and pencil become useless by replacing them by their numeric counterpart. Obviously, we are far from this dream. However, with the advent of Pocket PC, and the Pocket Framework specifically, I've found a powerful tool in the pursuit of this dream.

In my quest for the perfect project for the Code Project competition, I happened to find one of those little pieces of paper that my girlfriend uses, week after week, for her shopping list. Great! I've found my project, and also I've found a way that pencil and paper become useless. I'm going to build a Pocket PC application for shopping planning!

This article is written as an extremely condensed analysis document. You will find information regarding the requirements, the user interface guideline, the system's design, and finally, a section where you will find implementation details about some of the most interesting parts of the code.

Terminology

The following terminology is used throughout the Shopping App discussions:

  • Cart: Represents a list of Cart Items. This is a shopping list, the numeric counterpart of a piece of paper used for shopping planning.
  • Cart Item: Represents a specific item in a Cart, each item being a product you want to buy.
  • Product: A product is a Cart Item.

Background - The User Requirements

The main challenge here with the shopping application was not really the code part, but the design part. Obviously, the goal was to build a funny application, but before all, a useful one that can really be integrated in day to day life.

The requirements for the application can be summarized as:

  • User intuitive: People don't read help files! I think any professional developer who's involved with customers will confirm that people don't read help files. Application should be intuitive and user friendly or else people will not use it.
  • User should have the possibility to categorize things as much as possible in order to filter information.
  • User should have the possibility to define products for quick entry.
  • User should have the possibility to define products' units. Each product should offer a default unit which is empty by default.
  • User input should be kept to a minimum.
  • Using the application should be an advantage versus using a piece of paper: if the user does not get benefits from using the Shopping application, he will get rid of it.

The Shopping Application - User Interface Guideline

When the Shopping application opens, it displays a list of existing carts. The first time you open it, you face a blank screen. Available carts' list can be filtered to display carts that meet specific criteria based on the categories in which the cart belongs.

To add a new cart, either click on the New icon, or select an existing cart in the list and click on the Clone icon to use the selected cart as a template for your new cart. Opening an existing cart can be achieved either by double clicking a cart in the list, or by selecting a cart in the list and clicking the Open icon.

Figure 1 shows the initial screen with several carts that meet the current filter (Category = Grocery).

Starting screen for Shopping application.

Figure 1: Starting screen for shopping application.

Product Definition

Figure 2 shows the Product definition screen. This is where the user defines the products needed when creating a new Cart. You access the product definition screen by clicking on the Option button, then selecting Manage/Product Editor menu. To add a new product, click the New button and enter the product's name in the text box. Optionally, you can specify a default unit for each product. Click the Add button to add the product. Changes are automatically saved as the window closes.

Product Definition screen.

Figure 2: Product Definition screen.

Unit Definition

Figure 3 shows the Unit definition screen. This is where the user defines the product's units. You access the unit definition screen by clicking on the Option button, then selecting Manage/Unit Editor menu. To add a new unit, click the New button and enter the unit's name in the text box. Click the Add button to add the unit. Changes are automatically saved as the window closes.

Unit Definition screen.

Figure 3: Unit Definition screen.

Using the Cart Screen

The Cart screen is the numeric counterpart of a paper based shopping list. This screen presents the shopping list items with the following information: product's name, quantity, format, and notification icon (a note icon stands next to the product's name if there is a note associated with the entry). Cart's title and category can be changed on the Properties tab.

The Plus and X icons are used to add and remove items in the list. Items can also be moved up and down on the list with the Up and Down arrow icons. The last icon is used to toggle the operating mode from shopping to editing. In shopping mode, an item can be set as checked by clicking on it with the stylet. While in shopping mode, it is not possible to add or remove an item.

Changes are automatically saved as the window closes.

Cart screen. This is the numeric counterpart of a paper based shopping list.

Figure 4: Cart screen.

The Item Editor

This screen shows off when you click the Plus icon in the Cart screen, or when an existing item is double-clicked. To add a new item to the list, select a product from the list, specify the quantity, and optionally change the item's unit if it is not the correct one.

The products list can be easily filtered by using the ToggleCategory button. When you click on a toggle category (Mno, for example), then only products beginning with the letter 'm' or greater are displayed. Clicking repetitively on a toggled category alternates the category's letters (Mno, mNo, mnO, Mno ...).

The Notes tab contains a text area used to add a note to the item. As mentioned previously, when a note is attached to an item, an icon stands next to the item's name.

Changes are saved with the Saved (green) button, while the Cancel (red) button is used to cancel changes.

Item Editor Screen.

Figure 5: Item Editor Screen.

Design & Implementation

The design follows the 2-tier architecture (user interface, business logic). The data-layer tier has been included in the business rule to simplify. The project has been divided into three assemblies:

  • Shopping.GUI: this is the executable. All forms can be found there.
  • McSoft.UILib: All user controls used by the Shopping assembly are located there.
  • Shopping.Engine: this is the business rules.

The application's design is rather simple. The business rules consist in only six public classes.

  • ShoppingApp: This class is an abstraction of the application. This class contains several methods to manage carts like: creating, deleting, opening, and cloning.
  • Product: This class is mainly used by the Product Editor screen, it represents a single product. This class offers a serialize method that encapsulates the XML serialization of the products list.
  • Cart: This class is an abstraction of a shopping list. It contains a collection of CartItem and provides a serialize method that encapsulates the XML serialization of a Cart.
  • CartItem: This class is an abstraction of an item in a Cart. It provides a serialize method that encapsulates the XML serialization of a single item.
  • ProductsComparer: This class is used for custom sorting of ArrayList. For more information, see section: Implementing Custom sorting on ArrayList with IComparer.
  • CST: This is a utility class where you will find only public constants that are used by other assemblies.

User Controls and Double Buffering

Several issues with the Compact Framework were raised during the coding of the Shopping application. However, the most obvious one is the fact that available user controls are very limited in terms of features and diversity. As an example, the Button control does not have a picture property, which is a shame. So, I decided I had to get my hands dirty and write my own controls.

I wrote 9 user controls and 2 supporting classes for this project. I will not go into the details of each control but I will pinpoint some of the most helpful tips to writing your own controls for the Compact Framework.

  • For each control you write, override the OnClick method, and be sure that the following code is present:
    protected override void OnClick(EventArgs e)
    {
        this.Focus();
        base.OnClick(e);
    }

    If you forget to do so, clicking on your control does not set the focus on it. The side effect is that your other controls will not receive the LostFocus event. In my case, I solved the problem by creating an abstract class, inheriting from Control (see McSoftControl). All my controls inherit from this class, so I don't need to care about it. If you override OnClick for any of the descendant controls, don't forget to call base.OnClick().

  • If you write your own controls, the first thing you will discover is, to do fancy and cool controls, you absolutely need to understand how to override the OnPaint event and custom draw your control. I will not go into details on how to use the Graphics class. However, I want to specify that if you want to do a clean job, you need to use double buffering in order to remove flickering.

    Double buffering is a technique where you render your control into an image buffer into memory, then update the actual control's display with the buffer's contents. The following piece of code demonstrates the technique as you can find it in the CartView class.

    protected override void OnPaint(PaintEventArgs e)
    {
        Bitmap offScreen = new Bitmap(this.ClientSize.Width, 
                                    this.ClientSize.Height);
        Graphics gOffScreen = Graphics.FromImage(offScreen);
        
        // ... Do your drawing here by using the gOffScreen instance. 
        
        e.Graphics.DrawImage(offScreen, 0, 0, 
           this.ClientRectangle, GraphicsUnit.Pixel);
        gOffScreen.Dispose();
    }

    Also, when using double buffering this way, do not forget to override OnPaintBackground, but without any implementation, like in the following:

    protected override void OnPaintBackground(PaintEventArgs e)
    {
        // DO NOT REMOVE THIS METHOD OR FLICKERING WILL OCCURS
    }

Implementing Custom sorting on ArrayList with IComparer

One of my favorite classes in the .NET framework is the SortedList collection. Unfortunately, this class does not exist in the Compact Framework. My first intend was to use the SortedList collection to add the available products in order to sort them based on their name. After a quick research, I've found, it is possible to achieve the same functionality with an ArrayList collection and a custom comparer based on IComparer.

In my case, I have created a custom comparer called ProductsComparer which compares the name property of two instances of Product objects. Here is the complete implementation of the ProductsComparer class:

public class ProductsComparer : IComparer
{
   int IComparer.Compare(Object x, Object y)
   {
      return( (Product)x).Name.CompareTo( ((Product)y).Name);
   }
}

And here is where I use this class to sort an ArrayList of Product instances based on their name property:

    // Note: mProducts is an ArrayList
    IComparer myComparer = new ProductsComparer();
    mProducts.Sort(myComparer);

Implementing the OnDoubleClick Event

Do not search for the OnDoubleClick event in the Compact Framework, it doesn't exist. I had in mind to override the OnDoubleClick events on my lists in order to allow a cart to be opened when the user double clicks a cart in the list. Fortunately, this event can be easily simulated with the OnClick event. Here is how I have implemented it in OwnerDrawnListView class (base class for CartsView and CartView):

namespace McSoft.UILib
{
    public delegate void DoubleClickEventHandler(object sender, EventArgs e);
    
    public abstract class OwnerDrawnListView : McSoftControl
    {  
    // Partial class implementation to demonstrate
    // OnDoubleClick event, see class 
    // OwnerDrawnListView for full implementation
      
        public event DoubleClickEventHandler OnDoubleClick;
        private int previousClick = SystemInformation.DoubleClickTime + 1;
        
        protected override OnClick(EventArgs e)
        {
            int now = System.Environment.TickCount;
            if(now - previousClick <= System.information.DoubleClickTime)
              if(OnDoubleClick != null) OnDoubleClick(this.selectedIndex, e);
            
            previousClick = now;
            base.onClick (e);
        }
    }
}

History

This is release 1.0 of the application.

Road Map

  • Add prices to products.
  • Add categories to products.
  • Clean code to merge together Product, Unit and Category editor.
  • Update Carts filtering with more powerful filters.
  • Add an option page where users can change application's color, delete confirmation, etc...

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Dany McCarthy
Architect Multitel
Canada Canada
I am located in Quebec city, Canada. I have a Bachelor degree in Computer Science and another one in Economic science.
 
I currently work as a software architect for Multitel. I am specialized in backend development. I develop in C# since its inception but I also worked as a C++ software developer in the past.

Comments and Discussions

 
GeneralI have a working problem with this solution file? [modified] Pingrouphamityildirim21-Aug-10 14:06 
QuestionQuestion about shopping application PinmemberGnandt Robi10-Feb-09 23:02 
QuestionVer 2.0? Pinmembercloudno923-Mar-06 9:58 
AnswerRe: Ver 2.0? PinmemberDany McCarthy23-Mar-06 14:33 
GeneralFeature suggestion PinsussAnonymous7-Jun-04 8:51 
GeneralRe: Feature suggestion PinmemberDany McCarthy7-Jun-04 15:48 
GeneralRe: Feature suggestion Pinmembervcorreia7-Jun-04 23:05 
GeneralRe: Feature suggestion Pinmembermccdan8-Jun-04 2:37 
GeneralRe: Feature suggestion Pinmembervampiresoft12-Dec-04 19:32 
GeneralRe: Feature suggestion PinmemberDany McCarthy13-Dec-04 15:19 
GeneralRe: Feature suggestion Pinmembercpetzny16-Feb-05 2:09 
GeneralRe: Feature suggestion PinmemberDany McCarthy16-Feb-05 11:02 
GeneralRe: Feature suggestion Pinmemberdtimme27-Aug-05 21:03 
GeneralRe: Feature suggestion PinmemberDany McCarthy7-Sep-05 8:35 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.141022.1 | Last Updated 29 May 2004
Article Copyright 2004 by Dany McCarthy
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid