Click here to Skip to main content
15,884,176 members
Articles / General Programming
Tip/Trick

Duplicate Notifier for a List using ObservableCollection

Rate me:
Please Sign up or sign in to vote.
5.00/5 (4 votes)
7 Mar 2012CPOL1 min read 21.1K   163   3   1
Duplicate Notifier for a List using ObservableCollection.

Introduction

The normal List class in C# is not capable of providing notifications when an item is added or removed. The .NET Framework provides an ObservableCollection class which is capable of providing these features. In this Article I will demonstrate how ObservableCollection can be used to prevent the addition of a duplicate entry into a List/Collection.

Background 

The overall concept is demonstrated using two simple classes Company and Customer. Company can have many customers but if anyone tries to add a duplicate customer to a Company, that will not be allowed and an exception will be thrown. 

Using the code

The class Customer consists of two properties Id, Name and a constructor to set the values for these properties. 

The class Company consist of properties Id, Name, Customers, and a constructor to set values for these properties.

It also associates the CustomerCollectionChanged method to the CollectionChanged event of the ObservableCollection

C#
/// <summary>
/// Customers collection 
/// </summary>
private ObservableCollection<Customer> customers = null;

/// <summary>
/// Gets the customers of the Company
/// </summary>
public IList<Customer> Customers
{
    get
    {
        return this.customers;
    }

    private set
    {
        this.customers = new ObservableCollection<Customer>(value);
    }
}

/// <summary>
/// Initializes a new instance of the Company class with  ID and Name as Parameter
/// </summary>
/// <param name="id">Company ID.</param>
/// <param name="name">Company Name</param>
public Company(int id, string name)
{
    this.customers = new ObservableCollection<Customer>();
    this.customers.CollectionChanged += this.CustomerCollectionChanged;
    this.Id = id;
    this.Name = name;
}

Whenever a customer is added to the Customers list of the Company, the CustomerCollectionChanged method will be invoked which in turn invokes the ValidateCustomerCollection to prevent the duplicate entry into the Customers list.

C#
/// <summary>
/// Customer collection changed event
/// </summary>
/// <param name="sender">sender is collection</param>
/// <param name="e">event argument of NotifyCollectionChangedEventArgs</param>
private void CustomerCollectionChanged(object sender, 
        System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
    ValidateCustomerCollection(e);
}

/// <summary>
/// helper function to validate for duplicate customer.
/// </summary>
/// <param name="eventArg">
/// The event arg.
/// </param>
private  void ValidateCustomerCollection(NotifyCollectionChangedEventArgs eventArg)
{
    
   if (eventArg.Action == NotifyCollectionChangedAction.Add || 
                eventArg.Action == NotifyCollectionChangedAction.Replace)
    {
        for (int i = 0; i < eventArg.NewItems.Count; i++)
        {
            Customer customer = eventArg.NewItems[i] as Customer;

            if (Customers.Where(c => c.Id == customer.Id).Count() > 1)
            {
                customers.Remove(customer);
                throw new ArgumentException("Customer cannot be duplicated.");
            }
        }
    }
}

The Unit Test project contains the positive and negative scenarios for testing the Customers list validation.

C#
[TestMethod]
public void CreateCompany()
{
    int count = 0;
    int[] arr = new int[] { 101, 102, 103 };

    Company company = new Company(201, "Microsoft");
    Customer customer1 = new Customer(101,"Walmart");
    Customer customer2 = new Customer(102, "Tesco");
    Customer customer3 = new Customer(103, "QFC");
    
    //adding unique customers to company     
    company.Customers.Add(customer1);
    company.Customers.Add(customer2);
    company.Customers.Add(customer3);

    foreach (Customer c in company.Customers)
    {
        Assert.AreEqual(arr[count++],c.Id);
    }
}

[TestMethod]
public void CreateCompanyWithException()
{
    try
    {
        Company company = new Company(201, "Microsoft");
        Customer customer1 = new Customer(101, "Walmart");
        
        //adding duplicate customer to company
        company.Customers.Add(customer1);
        company.Customers.Add(customer1);
    }
    catch (ArgumentException ex)
    {
         Assert.AreEqual("Customer cannot be duplicated.", ex.Message);
    }
}

You can download the source code DuplicateNotifierList.zip.

History

  • This is the first version as on 7 March 2012.

License

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


Written By
Architect Collabera Solutions
India India
He has been programming for 11+ years in Microsoft Technologies.Now he works for Collabera Solutions, Bangalore. He is an MCP professional and he loves Playing Keyboard and Guitar on his free time.

Comments and Discussions

 
QuestionI Love this Pin
ruffone28-May-12 15:49
ruffone28-May-12 15:49 
It was exactly what I needed. Every thing else I saw was so complex. Thank you so much.

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

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