![]() |
Platforms, Frameworks & Libraries »
Mobile Development »
Applications
Intermediate
Shopping - A .NET shopping application for Pocket PCBy Dany McCarthyShopping 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. |
C#, VC7.1, Windows, .NET CF, .NET, MobileVS.NET2003, Dev
|
|
Advanced Search |
|
|
|
||||||||||||||||
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.
The following terminology is used throughout the Shopping App discussions:
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:
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).

Figure 1: Starting screen for shopping application.
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.

Figure 2: Product Definition screen.
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.

Figure 3: Unit Definition 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.

Figure 4: Cart screen.
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.

Figure 5: Item Editor Screen.
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:
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. 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.
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().
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
}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);
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);
}
}
}
This is release 1.0 of the application.
| You must Sign In to use this message board. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 28 May 2004 Editor: Smitha Vijayan |
Copyright 2004 by Dany McCarthy Everything else Copyright © CodeProject, 1999-2009 Web20 | Advertise on the Code Project |