Utilization of ObservableCollection in C#

ObservableCollection<T>

ObservableCollection<T> is a specialized collection class that is part of the .NET Framework in the `System.Collections.ObjectModel` namespace. It shares similarities with `List<T>`, but it offers additional features that are specifically designed for data binding scenarios, especially in UI frameworks like WPF (Windows Presentation Foundation) and UWP (Universal Windows Platform).

Here are some important aspects of `ObservableCollection<T>.

Advantages it has over a generic List<T>

  1. Change Notification: One of the main advantages of `ObservableCollection<T>` is that it implements the `INotifyCollectionChanged` interface. This means that it automatically notifies subscribers, such as UI controls, when its contents change. As a result, the UI can be dynamically updated without any manual intervention.
  2. Integration with Data Binding: `ObservableCollection<T>` is seamlessly integrated with data binding mechanisms in UI frameworks. It is commonly used as a data source for UI controls like list boxes, combo boxes, and data grids. Whenever items are added, removed, or modified in the collection, the UI elements bound to it automatically reflect those changes.
  3. Automatic UI Updates: When used in conjunction with data binding, any changes made to an `ObservableCollection<T>` are automatically propagated to the associated UI controls. This eliminates the need to manually update the UI when the underlying data changes.
  4. WPF and UWP Compatibility: `ObservableCollection<T>` is specifically designed for use in WPF and UWP applications. It is optimized for scenarios where dynamic data updates are common, such as lists of items in a user interface.
  5. Simplified MVVM Pattern: In the Model-View-ViewModel (MVVM) architectural pattern, which is commonly used in WPF and UWP applications, `ObservableCollection<T>` simplifies the responsibility of the ViewModel in managing collections of data. ViewModel classes can expose `ObservableCollection<T>` properties, and any changes to these collections automatically reflect in the associated Views.

In comparison, a List<T> lacks inherent change notification features. When utilizing a List<T> as a data source in a UI framework, it becomes necessary to manually refresh the UI each time the list undergoes modifications, a process that can be tedious and prone to errors, particularly in intricate situations.

On the whole, ObservableCollection<T> proves to be a valuable asset for handling dynamic data collections in WPF, UWP, and related frameworks, providing automatic change notification and smooth integration with data binding mechanisms.

Demonstration of ObservableCollection

using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Windows.Threading;

namespace WpfApp1
{
    internal class ObservableCollectionExample
    {
        ObservableCollection<EmployeeInfo> myObservableCollection;

        public ObservableCollectionExample()
        {
            // Define your ObservableCollection
            myObservableCollection = new ObservableCollection<EmployeeInfo>();

            // Subscribe to the CollectionChanged event
            myObservableCollection.CollectionChanged += MyObservableCollection_CollectionChanged;
        }

        // Handle the CollectionChanged event
        private void MyObservableCollection_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
        {
            // Check if the change was an Add or Remove operation
            if (e.Action == NotifyCollectionChangedAction.Add)
            {
                // Perform any logic related to Add operation
                MessageBox.Show("Item added");
            }
            else if (e.Action == NotifyCollectionChangedAction.Remove)
            {
                // Perform any logic related to Remove operation
                MessageBox.Show("Item removed");
            }

            // Defer any further modifications to the collection until after this event handler completes
            Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() =>
            {
                // Perform any deferred modifications here
            }));
        }
    }

    public class EmployeeInfo
    {
        public int UserId { get; set; }
        public string UserName { get; set; }
    }
}

Explanation of the above code

  • The ObservableCollectionExample Class serves as an example of how to utilize the ObservableCollection. Its main responsibility is to manage an ObservableCollection of EmployeeInfo objects.
  • The field myObservableCollection is declared as an ObservableCollection<EmployeeInfo>. This field holds the collection of EmployeeInfo objects.
  • In the constructor ObservableCollectionExample(), an instance of ObservableCollection<EmployeeInfo> is created and assigned to myObservableCollection. Additionally, the CollectionChanged event of myObservableCollection is subscribed to, with the event handler MyObservableCollection_CollectionChanged.
  • The event handler MyObservableCollection_CollectionChanged is responsible for handling the CollectionChanged event of myObservableCollection. Within this method, we examine the Action property of the NotifyCollectionChangedEventArgs parameter e to determine whether items were added or removed from the collection. Based on the action, we execute the appropriate logic, which in this case involves displaying a message box.
  • To ensure that any modifications to the collection occur after the current event handler finishes, modifications within the event handler are deferred using Dispatcher.CurrentDispatcher.BeginInvoke. This precautionary measure prevents potential issues, such as modifying the collection during a CollectionChanged event.
  • The EmployeeInfo Class defines a straightforward data structure with properties for UserId and UserName. It serves as the type parameter for the ObservableCollection.