PropertyChanged
This rule is triggered when a property of an item in the datasource is modified by code or by user input.
Warning
When modifying the properties of an item not present in the datasource, the # PropertyChanged rule is not triggered.
It can be used, for example, to update one property by using a formula based on other properties when the value of one of said properties changes.
Arguments
The Arguments property provides the following options.
| Name | Type | Description |
|---|---|---|
Item |
The type of the UI view model | Instance of the item whose property value changed. |
PropertyName |
string |
Name of the property whose value has changed. |
OldValue |
The type of the property. | Old value of the property. |
Value |
The type of the property. | New value of the property. |
Item versus DatasourceCurrent
Item refers to the item that has been added. It is the same as using Arguments.Item.
Important
The current position can be completely different from the position of the modified item, therefore, never assume that DatasourceCurrent refers to the modified item.
For example, when an action updates several items at once, DatasourceCurrent will only refer to one of the modified items.
To know more on the difference between the Item and DatasourceCurrent properties in an UI view event rule, you can check this article.
Examples
(Un)setting ShippedDate when OrderDate has changed.
if (Arguments.Value.HasValue)
{
Item.ShippedDate = Arguments.Value.Value.AddDays(3);
}
else
{
Item.ShippedDate = null;
}
Saving from PropertyChanged
In some custom scenarios, you may want to save immediately after a property change. A save is usually initiated by the normal UI workflow, but this pattern can still be useful when you need to persist a change from PropertyChanged.
Warning
Saving from a PropertyChanged rule is not recommended. In most cases, saving should be triggered by the normal UI workflow instead of being started directly from this rule.
The version below can block:
if (Item.UpdateFromClocking)
{
OrderUIViewModel? parent = this.GetMainViewModel();
if (parent != null && parent.HasChanges)
{
await parent.SaveDataAsync();
}
}
This happens because the save pipeline waits for pending UI event handlers to complete before sending data to the API. The current PropertyChanged rule is one of those pending handlers, but it cannot complete because it is itself waiting for SaveDataAsync() to finish.
Workaround 1: schedule the save without awaiting it
if (Item.UpdateFromClocking)
{
OrderUIViewModel? parent = this.GetMainViewModel();
if (parent != null && parent.HasChanges)
{
_ = parent.SaveDataAsync();
}
}
This lets the PropertyChanged rule complete first, so the save pipeline can then flush pending handlers and continue normally.
Caution
This is a pragmatic workaround. Because the save is no longer awaited, error handling and save sequencing become harder, and repeated triggers can start multiple concurrent saves.
Workaround 2: disable pending handler flushing on save
Behavior.FlushPendingEventHandlersOnSave = false;
This allows SaveDataAsync() to start without waiting for pending UI event handlers. It can solve the circular wait, but it also removes the stabilization step that normally happens before saving.
Use this option only when you fully control the surrounding asynchronous logic, because the save may run while other UI event handlers are still executing.