Skip to main content

The Importance of Property Change Notifications for Automatic UI Updates

  • 4 minutes to read

To display a consistent user interface, your XAF application must receive notifications from business classes when their property values are changed. For instance, Conditional Appearance and Validation modules may require an immediate UI update when a user modifies a certain value. This topic describes how to enable notifications from XPO, Entity Framework Core, and non-persistent business classes.

For non-collection properties (for example, for simple value types), the notification mechanism requires that the standard INotifyPropertyChanged interface is supported and its PropertyChanged event is implemented. To send a notification to internal XAF code, trigger PropertyChanged from a property set accessor within a business class.

Collection properties in data model classes must implement the following interfaces depending on the target ORM:

  • EF Core: INotifyCollectionChanged (for example, use ObservableCollection<T>)
  • XPO: IBindingList (for example, use XPCollection).

The collection notifies the ListView.CollectionSource and other XAF code about relevant changes through the INotifyCollectionChanged.CollectionChanged and IBindingList.ListChanged events respectively (when items are added or removed, when the entire collection is refreshed, etc.). The UI will update its data automatically to reflect appropriate changes. Each item in the collection should also implement the INotifyPropertyChanged interface to notify the UI when a property value is changed.

PropertyChanged and CollectionChanged Event in Entity Framework Core

XAF EF Core projects enable change-tracking proxies with the UseChangeTrackingProxies method. To support notifications in your business classes, define properties as described in the following article: Change-tracking proxies:

public class Blog {
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual IList<Post> Posts { get; } = new ObservableCollection<Post>();
}

While it is possible to use different generic types such as ICollection<T>, IList<T>, and so on for the public/external collection property declaration, the inner collection must implement the System.Collections.Specialized.INotifyCollectionChanged interface for change notifications through the INotifyCollectionChanged.CollectionChanged event (see above). We recommend that you use ObservableCollection<T> internally as the default option.

Important

In EF Core-based projects, the XAF Security System requires that Change Tracking is enabled when you work with DbContext.

If LINQ Expressions call the AsNoTracking() or AsNoTrackingWithIdentityResolution() method, or if Change Tracking is otherwise disabled, a data request becomes insecure. This may cause data to be retrieved from a database prohibited by the Security System.

PropertyChanged Event in XPO

You do not need to implement the INotifyPropertyChanged interface manually in an XPO business class. When you declare an XPO business class, you inherit BaseObject (or another base persistent class) that already supports this interface. You can trigger the PropertyChanged event from a property set accessor by executing the XPBaseObject.OnChanged or PersistentBase.SetPropertyValue helper method.

public class Department : BaseObject {
    // ...
    private string title;
    public string Title {
        get {
            return title;
        }
        set {
            SetPropertyValue(nameof(Title), ref title, value);
        }
    }
}

See Also: Creating a Persistent Object

PropertyChanged Event in Non-Persistent Classes

There are two ways to use the PropertyChanged event in a non-persistent class:

  • Inherit your non-persistent class from base non-persistent classes, as described in Non-Persistent Objects.

  • Implement this interface using the technique described above for the Entity Framework.

public class NonPersistentObject1 : INotifyPropertyChanged {
    // ...
    private string sampleProperty; 
    public string SampleProperty {
        get { return sampleProperty; }
        set {
            if (sampleProperty != value) {
                sampleProperty = value;
                OnPropertyChanged();
            }
        }
    }
    private void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = null) {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    public event PropertyChangedEventHandler PropertyChanged;
}

To create a new non-persistent class that supports INotifyPropertyChanged, use the XAF Business Object | Non-Persistent Object project item template.

NonPersistentObject

See Also