Home

Collections: The IList Interface

 

Introduction

While it provides the minimum functionality of a collection, the System::Collections::ICollection and the System::Collections::Generic::ICollection interfaces are not equipped to perform the regular operations of a collection class, such as adding, retrieving, or deleting items from a set.

To assist you with creating a collection class as complete as possible, the .NET Framework provides an interface named IList. The IList interface is defined in the System::Collections namespace and its equivalent of the same name is defined in the System::Collections::Generic namespace. The interface is equipped with the methods necessary to add, insert, delete, or retrieve items from a collection. Because the functionalities of these methods may not suit you, to use these features, you must create a class that implements them.

Practical LearningPractical Learning: Starting a Custom Collection Class

  1. Start Microsoft Visual Studio and create a new Windows Application named MusicalInstrumentStore2
  2. To create a dialog box, on the main menu, click Project -> Add New Item...
  3. In the Templates list, click Windows Form
  4. Set the name to CategoryEditor and click Add
  5. Design the form as follows:
     
    Control Text Name Other Properties
    Label &Category:    
    TextBox   txtCategory Modifiers: Public
    Button OK btnOK DialogResult: OK
    Button Cancel btnCancel DialogResult: Cancel
    Form Property Value
    FormBorderStyle FixedDialog
    Text Category Editor
    StartPosition CenterScreen
    AcceptButton btnOK
    CancelButton btnCancel
    MaximizeBox False
    MinimizeBox False
    ShowInTaskbar False
  6. To create a dialog box, on the main menu, click Project -> Add New Item...
  7. In the Templates list, if necessary, click Windows Form.
    Set the name to TypeEditor and click Add
  8. Design the form as follows:
     
    Musical Store Item Type
    Control Text Name Other Properties
    Label &Item Type:    
    TextBox   txtItemType Modifiers: Public
    Button OK btnOK DialogResult: OK
    Button Cancel btnCancel DialogResult: Cancel
    Form Property Value
    FormBorderStyle FixedDialog
    Text Type Editor
    StartPosition CenterScreen
    AcceptButton btnOK
    CancelButton btnCancel
    MaximizeBox False
    MinimizeBox False
    ShowInTaskbar False
  9. To create a dialog box, on the main menu, click Project -> Add New Item...
  10. Click Windows Form if necessary and set the name to ItemEditor
  11. Click Add
  12. Design the form as follows:
     
    Musical Store Item
     
    Control Text Name Other Properties
    Label &Item #:    
    TextBox   txtItemNumber  
    Label &Category:    
    ComboBox   cbxCategories  
    Button New C&ategory... btnNewCategory  
    Label &Item Type:    
    ComboBox   cbxItemTypes  
    Button New &Item Type... btnNewItemType  
    Label Item &Name:    
    TextBox   txtItemName  
    Label &Unit Price:    
    TextBox 0.00 txtUnitPrice TextAlign: Right
    Button Picture... btnPicture  
    TextBox   txtPicturePath  
    PictureBox   pbxPicturePath SizeMode: Zoom
    Button Create btnCreate  
    Button Close btnClose DialogResult: Cancel
    OpenFileDialog (Name): dlgOpen
    Title: Select Item Picture
    DefaultExt: jpg
    Filter: JPEG Files (*.jpg,*.jpeg)|*.jpg|GIF Files (*.gif)|*.gif|Bitmap Files (*.bmp)|*.bmp|PNG Files (*.png)|*.png
    Form Property Value
    FormBorderStyle FixedDialog
    Text Musical Instrument Store - Item Editor
    StartPosition CenterScreen
    MaximizeBox False
    MinimizeBox False
    ShowInTaskbar False
  13. Double-click the New Category button
  14. In the top section of the file, include the following header files:
     
    #pragma once
    
    #include "CategoryEditor.h"
    #include "TypeEditor.h"
    
    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;
  15. Scroll down and implement the event as follows:
      
    System::Void btnNewCategory_Click(System::Object^  sender, System::EventArgs^  e)
    {
        CategoryEditor ^ editor = gcnew CategoryEditor;
    
        if(editor->ShowDialog() == System::Windows::Forms::DialogResult::OK)
        {
            if(editor->txtCategory->Text->Length > 0)
            {
                String ^ category = editor->txtCategory->Text;
    
                // Make sure the category is not yet in the list
                if(cbxCategories->Items->Contains(category))
                    MessageBox::Show(category + L" is already in the list");
                else
                {
                    // Since this is a new category, add it to the combox box
                    cbxCategories->Items->Add(category);
                    // Just in case the user wanted to use this new category
                    // select it
                    cbxCategories->Text = category;
                }
            }
        }
    }
  16. Return to the Item Editor dialog box and double-click the New Item Type button
  17. Implement the event as follows:
      
    System::Void btnNewItemType_Click(System::Object^  sender, System::EventArgs^  e)
    {
        TypeEditor ^ editor = gcnew TypeEditor;
    
        if (editor->ShowDialog() == System::Windows::Forms::DialogResult::OK)
        {
            if (editor->txtItemType->Text->Length > 0)
            {
                String ^ type = editor->txtItemType->Text;
    
                // Make sure the type is not yet in the list
                if (cbxTypes->Items->Contains(type))
                    MessageBox::Show(L"The list already contains " + type);
                else
                {
                    cbxTypes->Items->Add(type);
                    cbxTypes->Text = type;
                 }
            }
        }
    }
  18. Return to the Item Editor dialog box and double-click the Picture button
  19. Implement the event as follows:
      
    System::Void btnPicture_Click(System::Object^  sender, System::EventArgs^  e)
    {
        if(dlgPicture->ShowDialog() == System::Windows::Forms::DialogResult::OK)
        {
            txtPicturePath->Text = dlgPicture->FileName;
    		pbxStoreItem->Image = Image::FromFile(txtPicturePath->Text);
        }
    }
  20. In the Solution Explorer, double-click Form1.h
  21. Design the form as follows:
     
    Musical Instrument Store
     
    Control Text Name Other Properties
    Label Label Item Category:    
    ComboBox ComboBox   cbxCategories  
    Label Label Items Type:    
    ComboBox ComboBox   cbxTypes  
    Label Label Available Items    
    Button Button New Store Item... btnNewStoreItem  
    ListView ListView   lvwStoreItems View: Details
    FullRowSelect: True
    GridLines: True
    Columns
    (Name) Text TextAlign Width
    colItemNumber Item #    
    colItemName Item Name/Description   320
    colUnitPrice Unit Price Right  
    PictureBox   pbxStoreItem SizeMode: Zoom
    GroupBox GroupBox Selected Items    
    Label Label Item #    
    Label Label Description    
    Label Label Unit Price    
    Label Label Qty    
    Label Label Sub Total    
    TextBox TextBox   txtItemNumber1  
    TextBox TextBox   txtDescription1  
    TextBox TextBox 0.00 txtUnitPrice1 TextAlign: Right
    TextBox TextBox 0 txtQuantity1 TextAlign: Right
    TextBox TextBox 0.00 txtSubTotal1 TextAlign: Right
    Button Button Remove btnRemove1  
    TextBox TextBox   txtItemNumber2  
    TextBox TextBox   txtDescription2  
    TextBox TextBox 0.00 txtUnitPrice2 TextAlign: Right
    TextBox TextBox 0 txtQuantity2 TextAlign: Right
    TextBox TextBox 0.00 txtSubTotal2 TextAlign: Right
    Button Button Remove btnRemove2  
    TextBox TextBox   txtItemNumber3  
    TextBox TextBox   txtDescription3  
    TextBox TextBox 0.00 txtUnitPrice3 TextAlign: Right
    TextBox TextBox 0 txtQuantity3 TextAlign: Right
    TextBox TextBox 0.00 txtSubTotal3 TextAlign: Right
    Button Button Remove btnRemove3  
    TextBox TextBox   txtItemNumber4  
    TextBox TextBox   txtDescription4  
    TextBox TextBox 0.00 txtUnitPrice4 TextAlign: Right
    TextBox TextBox 0 txtQuantity4 TextAlign: Right
    TextBox TextBox 0.00 txtSubTotal4 TextAlign: Right
    Button Button Remove btnRemove4  
    TextBox TextBox   txtItemNumber5  
    TextBox TextBox   txtDescription5  
    TextBox TextBox 0.00 txtUnitPrice5 TextAlign: Right
    TextBox TextBox 0 txtQuantity5 TextAlign: Right
    TextBox TextBox 0.00 txtSubTotal5 TextAlign: Right
    Button Button Remove btnRemove5  
    TextBox TextBox   txtItemNumber6  
    TextBox TextBox   txtDescription6  
    TextBox TextBox 0.00 txtUnitPrice6 TextAlign: Right
    TextBox TextBox 0 txtQuantity6 TextAlign: Right
    TextBox TextBox 0.00 txtSubTotal6 TextAlign: Right
    Button Button Remove btnRemove6  
    GroupBox GroupBox Order Summary    
    Label Label Items Total:    
    TextBox TextBox 0.00 txtItemsTotal TextAlign: Right
    Label Label Tax Rate:    
    TextBox TextBox 7.75   TextAlign: Right
    Label Label %    
    Label Label Tax Amount:    
    TextBox TextBox 0.00 txtTaxAmount TextAlign: Right
    Label Label Order Total:    
    TextBox TextBox 0.00 txtOrderTotal TextAlign: Right
    Button Button Save btnSave  
    Label Label Receipt #:    
    TextBox TextBox 0.00 txtReceiptNumber  
    Button Button &Open btnOpen  
    Button Button New Order btnNewOrder  
    Button Button Close btnClose  
  22. To create a new class, in the Solution Explorer, right-click MusicalInstrumentStore2 -> Add -> Class...
  23. In the Templates list, click C++ Class
  24. Click Add
  25. Set the Name to CStoreItem
  26. Click Finish
  27. Change the header file as follows:
     
    #pragma once
    using namespace System;
    
    [Serializable]
    public ref class CStoreItem
    {
    private:
        String ^ nbr;
        String ^ cat;
        String ^ tp;
        String ^ nm;
        double   prc;
    
    public:
        CStoreItem(void);
        CStoreItem(String ^ itmNumber);
        CStoreItem(String ^ itmNumber, String ^ category,
                   String ^ type, String ^ name, double price);
    
        property String ^ ItemNumber
        {
            String ^ get() { return nbr; }
            void set(String ^ value) { nbr = value; }
        }
    
        property String ^ Category
        {
            String ^ get() { return cat; }
            void set(String ^ value) { cat = value; }
        }
    
        property String ^ Type
        {
            String ^ get() { return tp; }
            void set(String ^ value) { tp = value; }
        }
    
        property String ^ ItemName
        {
            String ^ get() { return nm; }
            void set(String ^ value) { nm = value; }
        }
    
        property double UnitPrice
        {
            double get() { return prc; }
            void set(double value) { prc = value; }
        }
    
        bool Equals(CStoreItem ^ same);
    };
  28. Change the source file as follows:
      
    #include "StdAfx.h"
    #include "StoreItem.h"
    
    CStoreItem::CStoreItem(void)
    {
        nbr = L"000000";
        cat = L"Accessories";
        tp  = L"Accessories";
        nm  = L"Unknown";
        prc = 0.00;
    }
    
    CStoreItem::CStoreItem(String ^ itmNumber)
    {
        nbr = itmNumber;
        cat = L"Accessories";
        tp  = L"Accessories";
        nm  = L"Unknown";
        prc = 0.00;
    }
    
    CStoreItem::CStoreItem(String ^ itmNumber, String ^ category,
                           String ^ type, String ^ name, double price)
    {
        nbr = itmNumber;
        cat = category;
        tp  = type;
        nm  = name;
        prc = price;
    }
    
    bool CStoreItem::Equals(CStoreItem ^ same)
    {
        if( (nbr == same->nbr) &&
            (cat == same->cat) &&
            (tp  == same->tp) &&
            (nm  == same->nm) &&
            (prc == same->prc))
            return true;
        else
            return false;
    }
  29. Save the file
 

 

 

Implementing IList

As mentioned above, to create a collection, you can derive it from the IList interface. Here is an example:

#pragma once
using namespace System::Collections;

public ref class CBookList : public IList
{
};

This System::Collections::IList interface is declared as follows:

public interface class IList : ICollection, IEnumerable

This System::Collections::Generic::IList interface is declared as follows:

generic<typename T>
public interface class IList : ICollection<T>, 
	                       IEnumerable<T>,
			       IEnumerable

This means that the IList interface extends both the ICollection and the IEnumerable interfaces. This also implies that you must implement the members of these parent interfaces. In other words, you must implement the Count property, the SyncRoot property, the IsSynchronized property, and the CopyTo() method of the ICollection interface. From what we learned with ICollection, here are examples of implementing these members for the System::Collections::IList interface:

Header File: BookList.h

#pragma once
using namespace System;
using namespace System::Collections;

public ref class CBookList : public IList
{
private:
    int counter;
    array<Object ^> ^ objs;

public:
	CBookList(void);

    virtual property int Count
    {
        int get() { return counter; }
    }

    virtual property bool IsSynchronized
    {
        bool get() { return false; }
    }

    virtual property Object ^ SyncRoot
    {
        Object ^ get() { return this; }
    }

    virtual void CopyTo(Array ^ ary, int index);
};

Source File: BookList.cpp

#include "BookList.h"

CBookList::CBookList(void)
	: counter(0),
      objs(gcnew array<Object ^>(5))
{
}

void CBookList::CopyTo(Array ^ ary, int index)
{
}

You must also implement the System::Collections::GetEnumerator() (or the System::Collections::Generic::GetEnumerator()) method of the System::Collections::IEnumerable  (or of the System::Collections::Generic::IEnumerable) interface. If you don't have time to completely implement it, you can simply return nullptr. Here is an example for the System::Collections::IList interface:

Header File: BookList.h

#pragma once
using namespace System;
using namespace System::Collections;

public ref class CBookList : public IList
{
private:
    int counter;
    array<Object ^> ^ objs;

public:
	CBookList(void);

    virtual property int Count
    {
        int get() { return counter; }
    }

    virtual property bool IsSynchronized
    {
        bool get() { return false; }
    }

    virtual property Object ^ SyncRoot
    {
        Object ^ get() { return this; }
    }

    virtual void CopyTo(Array ^ ary, int index);
    virtual IEnumerator ^ GetEnumerator();
};

Source File: BookList.cpp

#include "BookList.h"

CBookList::CBookList(void)
    : counter(0),
      objs(gcnew array<Object ^>(5))
{
}

void CBookList::CopyTo(Array ^ ary, int index)
{
}

IEnumerator ^ CBookList::GetEnumerator()
{
    return nullptr;
}

Practical LearningPractical Learning: Implementing the IList Interface

  1. To create a new class, in the Class View, right-click MusicalInstrumentStore2 -> Add -> Class...
  2. In the Templates, if necessary, click C++ Class. Click Add
  3. Set the Name to CStoreItems
  4. Click Finish
  5. Change the header file as follows:
     
    #pragma once
    using namespace System;
    using namespace System::Collections;
    
    [Serializable]
    public ref class CStoreItems : public IList
    {
    private:
        int counter;
        array<Object ^> ^ items;
    
    public:
        CStoreItems(void);
    
        virtual property int Count
        {
            int get() { return counter; }
        }
    
        virtual property bool IsSynchronized
        {
            bool get() { return false; }
        }
    
        virtual property Object ^ SyncRoot
        {
            Object ^ get() { return this; }
        }
    
        virtual void CopyTo(Array ^ arr, int index);
        virtual IEnumerator ^ GetEnumerator();
    };
  6. Change the source file as follows:
      
    #include "StdAfx.h"
    #include "StoreItems.h"
    
    CStoreItems::CStoreItems(void)
        : counter(0),
          items(gcnew array<Object ^>(5))
    {
    }
    
    void CStoreItems::CopyTo(Array ^ arr, int index)
    {
    }
    
    IEnumerator ^ CStoreItems::GetEnumerator()
    {
        return nullptr;
    }
  7. Save the file
 
 
   
 

Previous Copyright © 2009-2010 FunctionX, Inc. Next