Imports System.Collections.ObjectModel Imports System.ComponentModel Public NotInheritable Class CustomerData Private Sub New() End Sub Public Shared Function GetCustomers() As ObservableCollection(Of Customer) Dim list As New ObservableCollection(Of Customer)() 'Add Customers to the ObservableCollection using Object Initializers. list.Add(New Customer With {.ID = 123, .FullName = New Name With {.FirstName = "John", .LastName = "Smith"}}) list.Add(New Customer With {.ID = 456, .FullName = New Name With {.FirstName = "John", .LastName = "Smith"}}) list.Add(New Customer With {.ID = 789, .FullName = New Name With {.FirstName = "Mary", .LastName = "Smith"}}) 'You can still use the old way of creating objects, setting properties, and then adding them to the collection as shown in the commented code below. 'Customer customer; 'Name name; 'customer = new Customer(); 'customer.ID = 123; 'name = new Name(); 'name.FirstName = "John"; 'name.LastName = "Smith"; 'customer.FullName = name; 'list.Add(customer); 'customer = new Customer(); 'customer.ID = 456; 'name = new Name(); 'name.FirstName = "Mike"; 'name.LastName = "Smith"; 'customer.FullName = name; 'list.Add(customer); 'customer = new Customer(); 'customer.ID = 789; 'name = new Name(); 'name.FirstName = "Mary"; 'name.LastName = "Smith"; 'customer.FullName = name; 'list.Add(customer); Return list End Function End Class Public Class Customer Implements INotifyPropertyChanged Private _id As Integer Public Property ID() As Integer Get Return _id End Get Set(ByVal value As Integer) If _id <> value Then _id = value OnPropertyChanged("ID") End If End Set End Property Private _fullName As Name Public Property FullName() As Name Get Return _fullName End Get Set(ByVal value As Name) If _fullName <> value Then _fullName = value OnPropertyChanged("FullName") End If End Set End Property #Region "INotifyPropertyChanged Members" Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged #End Region Private Sub OnPropertyChanged(ByVal propertyName As String) RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName)) End Sub End Class Public Class Name Implements INotifyPropertyChanged Private _firstName As String Public Property FirstName() As String Get Return _firstName End Get Set(ByVal value As String) _firstName = value OnPropertyChanged("FirstName") End Set End Property Private _lastName As String Public Property LastName() As String Get Return _lastName End Get Set(ByVal value As String) _lastName = value OnPropertyChanged("LastName") End Set End Property #Region "Overrides" Public Shared Operator =(ByVal a As Name, ByVal b As Name) As Boolean If Object.ReferenceEquals(a, Nothing) AndAlso Object.ReferenceEquals(b, Nothing) Then Return True ElseIf Object.ReferenceEquals(a, Nothing) OrElse Object.ReferenceEquals(b, Nothing) Then Return False End If Return a.FirstName = b.FirstName AndAlso a.LastName = b.LastName End Operator Public Shared Operator <>(ByVal a As Name, ByVal b As Name) As Boolean Return Not (a = b) End Operator Public Overloads Overrides Function Equals(ByVal obj As Object) As Boolean Dim b As Name = TryCast(obj, Name) Return Me = b End Function Public Overloads Overrides Function GetHashCode() As Integer Return (Me.FirstName + " " + Me.LastName).GetHashCode() End Function #End Region #Region "INotifyPropertyChanged Members" Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged #End Region Private Sub OnPropertyChanged(ByVal propertyName As String) RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName)) End Sub End Class