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, useObservableCollection<T>
) - XPO:
IBindingList
(for example, useXPCollection
).
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.