Business Classes

To support the user interface, you need a set of simple business classes representing the photographs and the items the user can purchase based on each photo. These are collected in the StoreItems.cs file, shown in Example 4-2.

Example 4-2. StoreItems.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Media.Imaging;
using System.Collections.Specialized;
using System.Windows.Controls;

namespace PhotoCooperative
{
   public class ImageFile
   {
      public String Path { get; set; }
      public Uri TheUri { get; set; }
      public BitmapFrame Image { get; set; }

      public ImageFile(string path)
      {
         Path = path;
         TheUri = new Uri(Path);
         Image = BitmapFrame.Create(TheUri);
      }

      public override string ToString()
      {
         return Path;
      }

   }

   public class PhotoList : ObservableCollection<Image File>
   {
      DirectoryInfo theDirectoryInfo;

      public PhotoList() { }

      public PhotoList(string path) : this(new DirectoryInfo(path)) { }

      public PhotoList(DirectoryInfo directory)
      {
         theDirectoryInfo = directory;
         Update();
      }

      public string Path
      {
         set
         {
            theDirectoryInfo = new DirectoryInfo(value);
            Update();
         }
         get { return theDirectoryInfo.FullName; }
      }

      public DirectoryInfo Directory
      {
         set
         {
            theDirectoryInfo = value;
            Update();
         }
         get { return theDirectoryInfo; }
      }

      private void Update()
      {
         foreach (FileInfo f in theDirectoryInfo.GetFiles("*.gif"))
         {
            Add(new ImageFile(f.FullName));
         }
      }
   }

   public class PrintType
   {
      public String Description { get; set; }
      public double Price { get; set; }

      public PrintType(string description, double price)
      {
         Description = description;
         Price = price;
      }

      public override string ToString()
      {
         return Description;
      }

   }

   public class PrintTypeList : ObservableCollection<PrintType>
   {
      public PrintTypeList()
      {
         Add(new PrintType("5x7 Print", 0.49));
         Add(new PrintType("Holiday Card", 1.99));
         Add(new PrintType("Sweatshirt", 19.99));
      }
   }

   public class PrintBase : INotifyPropertyChanged
   {
      private BitmapSource aPhoto;
      private PrintType aPrintType;
      private int aQuantity;

      public PrintBase(BitmapSource photo, PrintType printtype, int quantity)
      {
         Photo = photo;
         PrintType = printtype;
         Quantity = quantity;
      }

      public PrintBase(BitmapSource photo, string description, double cost)
      {
         Photo = photo;
         PrintType = new PrintType(description, cost);
         Quantity = 0;
      }

      public BitmapSource Photo
      {
         set { aPhoto = value; OnPropertyChanged("Photo"); }
         get { return aPhoto; }
      }

      public PrintType PrintType
      {
         set { aPrintType = value; OnPropertyChanged("PrintType"); }
         get { return aPrintType; }
      }

      public int Quantity
      {
         set { aQuantity = value; OnPropertyChanged("Quantity"); }
         get { return aQuantity; }
      }

      public event PropertyChangedEventHandler PropertyChanged;

      private void OnPropertyChanged(String info)
      {
         if (PropertyChanged != null)
             PropertyChanged(this, new PropertyChangedEventArgs(info));
      }

      public override string ToString()
      {
         return PrintType.ToString();
      }
   }

   public class Print : PrintBase
   {
      public Print(BitmapSource photo) : base(photo, "5x7 Print", 0.49) { }
   }

   public class GreetingCard : PrintBase
   {
      public GreetingCard(BitmapSource photo) : base(photo, "Greeting Card", 1.99) 
      { }
   }

   public class SShirt : PrintBase
   {
      public SShirt(BitmapSource photo) : base(photo, "Sweatshirt", 19.99) { }
   }

   public class PrintList : ObservableCollection<PrintBase> { }
}

There's nothing terribly surprising in this code. In the ImageFile constructor, you first define the ImageFile object (the picture) based on its disk location. You create a URI from the path to the file on disk, and you create a BitmapFrame from that URI:

public ImageFile(string path)
{
   Path = path;
   TheUri = new Uri(Path);
   Image = BitmapFrame.Create(TheUri);
}

The PhotoList class represents an ObservableCollection of ImageFiles:

public class PhotoList : ObservableCollection<ImageFile>

ObservableCollection is a generic collection that implements the Observer pattern (discussed in Chapter 8); that is, it notifies interested (registered) objects when items are added or removed, or when the list is refreshed. This will come in handy later, when you create the scrolling listbox of photos from which the user can choose. Because the list is observable, when an item is selected an event will be raised. You can set an event handler accordingly:

<ListBox Style="{DynamicResource PhotoListStyle}"
    Grid.Row="1"
    Grid.ColumnSpan="3"
    Name ="PhotoListBox"
    Margin="0,0,0,20"
    DataContext="{Binding Source={StaticResource Photos}}"
    SelectionChanged ="PhotoListSelection"
    ItemsSource="{Binding }"
    ItemContainerStyle="{DynamicResource PhotoListItem}"
    SelectedIndex="0" />

You'll need one more business class, to validate credit cards, but we'll delay discussion of that until you're ready to build the second page.

Get Programming .NET 3.5 now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.