ImmutableEditableObjectAdapter 1.0.8
See the version list below for details.
dotnet add package ImmutableEditableObjectAdapter --version 1.0.8
NuGet\Install-Package ImmutableEditableObjectAdapter -Version 1.0.8
<PackageReference Include="ImmutableEditableObjectAdapter" Version="1.0.8" />
<PackageVersion Include="ImmutableEditableObjectAdapter" Version="1.0.8" />
<PackageReference Include="ImmutableEditableObjectAdapter" />
paket add ImmutableEditableObjectAdapter --version 1.0.8
#r "nuget: ImmutableEditableObjectAdapter, 1.0.8"
#:package ImmutableEditableObjectAdapter@1.0.8
#addin nuget:?package=ImmutableEditableObjectAdapter&version=1.0.8
#tool nuget:?package=ImmutableEditableObjectAdapter&version=1.0.8
ImmutableEditableObjectAdapter
Adapts immutable state record
s into an IEditableObject
replacing the record
on edit, intended for Binding
in a DataGrid
.
using System.ComponentModel;
Person p = new("Max", "Green", DateTimeOffset.Now.AddYears(-43));
EditablePerson editable = new(p);
editable.Edited += (s, e) => p = s.IsPropertyChanged(nameof(Person.Name)) ? e.NewValue : p;
editable.BeginEdit();
editable.Name = "Müller";
editable.EndEdit();
internal sealed record Person(string Name, string FavouriteColor, DateTimeOffset BirthDay);
internal sealed partial class EditablePerson : ImmutableEditableObjectAdapter<Person>;
Generated ImmutableEditableObjectAdapter
types mirrors the public
Properties of the record
passed as a generic type parameter. However, all properties have setter.
Each property, set to a different value than the property in the Unedited
reference, is used to reconstruct Unedited
into a new record
:
Person edited = Unedited with {
Name = NamePropertyChanged ? Name : Unedited.Name,
}
The constructed record is passed as NewValue
to the Edited
event, then set as the new Unedited
.
Customization
ImmutableEditableObjectAdapter
API allows customizing the creation of events.
/// <summary>
/// Provides the old, and new value of the <see cref="EditedEventHandler{TContract}"/>.
/// </summary>
/// <typeparam name="TContract">The type of the contract <c>record</c>.</typeparam>
public sealed class EditedEventArgs<TContract> : EventArgs
{
public TContract OldValue { get; }
public TContract NewValue { get; }
}
/// <summary>
/// Represents the method that will handle the <see cref="ImmutableEditableObjectAdapter{TContract}.Edited"/> event of an <see cref="ImmutableEditableObjectAdapter{TContract}"/> instance.
/// </summary>
/// <typeparam name="TContract">The type of the contract <c>record</c>.</typeparam>
public delegate void EditedEventHandler<TContract>(
ImmutableEditableObjectAdapter<TContract> sender,
EditedEventArgs<TContract> args
) where TContract : notnull;
/// <summary>
/// Derive a <c>sealed partial class</c> to generate a <see cref="IEditableObject"/> from a immutable state <c>record</c> type.
/// <br/>
/// Update the immutable state when the <see cref="Edited"/> event indicates the state is replaced.
/// </summary>
/// <typeparam name="TContract">The type of the contract <c>record</c>.</typeparam>
public abstract class ImmutableEditableObjectAdapter<TContract>
: IEditableObject, INotifyPropertyChanged, INotifyPropertyChanging
where TContract : notnull
{
/// <inheritdoc />
public event PropertyChangedEventHandler? PropertyChanged;
/// <inheritdoc />
public event PropertyChangingEventHandler? PropertyChanging;
/// <summary>
/// Occurs before <see cref="EndEdit"/> replaces the immutable state <c>record</c>.
/// </summary>
public event EditedEventHandler<TContract>? Edited;
/// <inheritdoc />
public abstract void BeginEdit();
/// <inheritdoc />
public abstract void CancelEdit();
/// <inheritdoc />
public abstract void EndEdit();
/// <summary>
/// Enumerate names of all changed properties during edit, and <see cref="Edited"/>.
/// </summary>
public abstract IEnumerable<string> ChangedProperties();
/// <summary>
/// Indicates whether the property with the name name has changed during edit, and <see cref="Edited"/>.
/// </summary>
public abstract bool IsPropertyChanged(string propertyName);
protected virtual void OnPropertyChanging([CallerMemberName] string? propertyName = null);
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null);
protected virtual void OnEdited(TContract oldValue, TContract newValue);
protected bool SetField<T>(ref T field, T value, [CallerMemberName] string? propertyName = null);
}
Learn more about Target Frameworks and .NET Standard.
This package has no dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.