Unmanaged struct backed INPC ViewModel, only raising PropertyChanged when backing field(s) changed

So, suppose we have a large unmanaged struct that we obtain from external source, suppose from a network resource. This unmanaged struct decomposes into a set of primitives, with various values.
public struct ExampleStruct
{
public int StructId;
public float StructRealAmount;
public DateTimeOffset StructTimestamp;
}
public struct ExampleStruct
{
public int StructId;
public float StructRealAmount;
public DateTimeOffset StructTimestamp;
}
and then we have our ViewModel class that implements INotifyPropertyChanged. I have made an example below, not using the above struct as a field.
public class ExampleViewModel : INotifyPropertyChanged
{
// INPC boilerplate, to be replaced perhaps with an MVVM toolkit later
public event PropertyChangedEventHandler? PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public static bool CheckChange<T>(ref T oldValue, T newValue, [CallerMemberName] string propertyName = "")
{
if (!Equals(oldValue, newValue))
{
oldValue = newValue;
OnPropertyChanged(propertyName);
return true;
}
return false;
}
// end INPC boilerplate

private int _viewModelId;
public int ViewModelId { get => _viewModelId; set => CheckChange(ref _viewModelId, value); }
private float _viewModelRealAmount;
public float ViewModelRealAmount { get => _viewModelRealAmount; set => CheckChange(ref _viewModelRealAmount, value); }
private DateTimeOffset _viewModelTimestamp;
public DateTimeOffset ViewModelTimestamp { get => _viewModelTimestamp; set => CheckChange(ref _viewModelTimestamp, value); }

// TODO: On receive ExampleStruct, set properties to fire events if data has changed
}
public class ExampleViewModel : INotifyPropertyChanged
{
// INPC boilerplate, to be replaced perhaps with an MVVM toolkit later
public event PropertyChangedEventHandler? PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public static bool CheckChange<T>(ref T oldValue, T newValue, [CallerMemberName] string propertyName = "")
{
if (!Equals(oldValue, newValue))
{
oldValue = newValue;
OnPropertyChanged(propertyName);
return true;
}
return false;
}
// end INPC boilerplate

private int _viewModelId;
public int ViewModelId { get => _viewModelId; set => CheckChange(ref _viewModelId, value); }
private float _viewModelRealAmount;
public float ViewModelRealAmount { get => _viewModelRealAmount; set => CheckChange(ref _viewModelRealAmount, value); }
private DateTimeOffset _viewModelTimestamp;
public DateTimeOffset ViewModelTimestamp { get => _viewModelTimestamp; set => CheckChange(ref _viewModelTimestamp, value); }

// TODO: On receive ExampleStruct, set properties to fire events if data has changed
}
I had a thought to in the View Model class just have a single field of the unmanaged struct, and then fire off events of property changed. But if I were to do that, how would one determine which properties were changed ? Would it be better to have the unmanaged struct as the sole backing field, or should I not do that?
2 Replies
RazorSharpFang
I have decided to not do that, and set each property in turn, which is only raise the property changed events for that property efficiently, whereas having a single backing field would make raising the events more difficult.
Accord
Accord2y ago
✅ This post has been marked as answered!