The previous post on CommunityToolkit.Mvvm covered the basics of Observable Entities using ObservableObject and ObservableProperty attributes. This post addresses an issue encountered when binding to an Observable Entity’s ToString() result where the bound entity is the complete ViewModel. A solution is provided.

In a Dialog had a binding that was a single entity:

Dialog: NewEventDialog

In entity class

[ObservableProperty]
private int? eventNumber;

public override string ToString()
{
		...
		...
	string result = $"Event No:{EventNumber} {TimeStr} {genderStr} {ageGroupingStr} {Distance}m {trackTypeStr} {Description}";
	return result;
}

Code Behind:

	public Event _event {get; set;}
   ...
	this.DataContext = _event;

Xaml Code

<TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" 
       FontStyle="Italic" FontWeight="Bold" Foreground="Blue"
       HorizontalAlignment="Center"
       Text ="{Binding}"
           />

But the Dialog was not populating the Binding.

Cause

The binding is to the whole Event object which, as intended, is meant to display the ToString() method. But that only occurs when the binding itself raises a SelfChanged notification.

Solution

Use a read-only property that returns the ToString() result, and manually raise a notification when properties used in ToString() change.

For example

Xaml:

        <TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" 
               FontStyle="Italic" FontWeight="Bold" Foreground="Blue"
               HorizontalAlignment="Center"
               Text ="{Binding Display}"
                   />

In class

        [ObservableProperty, NotifyPropertyChangedFor(nameof(Display))]
        private int? eventNumber;

	[JsonIgnore]
        [NotMapped]
        public string Display => ToString();

The Event Dialog

The Event Dialog
All good now! 😊

Clarification

If the Event was a property of the ViewModel, say as CurrentEvent, and the binding was to that property, then the ToString() method would be called automatically when the Event property changed.

For example the Xaml code would then be:

Xaml Code

<TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" 
       FontStyle="Italic" FontWeight="Bold" Foreground="Blue"
       HorizontalAlignment="Center"
       Text ="{Binding CurrentEvent}"
           />

Summary

When binding to an entire object, such as in this case, the ToString() method will not automatically update the UI when properties change. Instead, create a dedicated read-only property that returns the desired string representation and ensure that it raises property change notifications when any of its dependent properties change. This approach ensures that the UI remains in sync with the underlying data model.


 TopicSubtopic
   
 This Category Links 
Category:Application Dev Index:Application Dev
<  Prev:   CommunityToolkit.Mvvm