Description
Background and Motivation
When Editing large objects that contain other (child)objects it's not easily possible to determine if there are errors on a specific (child)object.
This API proposal adds three functions that use the provided (child)object to get ValidationMessages or get/set the IsModified state.
The current API can either get or set values based on the entire supplied model, or on 1 specific FieldIdentifier
this proposal adds the possibility to have an additional filter that uses the Model
property of the FieldIdentifier
.
Proposed API
public class EditContext
{
public IEnumerable<string> GetValidationMessages(object childObject)
public bool IsModified(object childObject)
public void MarkAsUnmodified(object childObject)
}
Implemented like:
public class EditContext
{
public IEnumerable<string> GetValidationMessages(object childObject)
{
foreach (var state in _fieldStates)
{
if (state.Key.Model == childObject)
{
foreach (var message in state.Value.GetValidationMessages())
{
yield return message;
}
}
}
}
public bool IsModified(object childObject)
{
foreach (var state in _fieldStates)
{
if (state.Key.Model == childObject && state.Value.IsModified)
{
return true;
}
}
return false;
}
public void MarkAsUnmodified(object childObject)
{
foreach (var state in _fieldStates)
{
if (state.Key.Model == childObject)
{
state.Value.IsModified = false;
}
}
}
}
Usage Examples
Imagine you have a Client object, this object holds values for personal details (name etc.). It also holds a collection of Addresses and a collection of CommunicationMethods (Phone numbers/ Email addresses etc.)
class Client
{
Person PersonalData { get; }
string ClientCode { get; set; }
}
class Person
{
string Name { get; set; }
IEnumerable<Address> Addresses { get; set; }
IEnumerable<Communication> Communicationss { get; set; }
}
As you can see in the below image, the user sees a red exclamation mark with Addresses:
And when the users select the Addresses Tab, indeed the user will see the problem.
Implementation without API proposal
I see 2 possibilities to achieve this functionality with the current API.
1.) Enclose the entire Client component in 1 EditForm
, to check if a specific subset (for example an address) has errors on it a user will have to create a foreach
loop that queries all FieldIdentifier
(or Expression<Func<object>>
accessor used by that Address. although feasible it's not very flexible, as a user will need to supply a list of FieldIdentifiers
or Expressions
used by that Address.
2.) Use separate EditForm
Components surrounding specific subsets of the data (1 for Personal Data, 1 for each Address, and 1 for each CommunicationMethod), and every time the validation state changes cache that state on the Main Client component so it can be used to display the error icon on Tabs.
Implementation with API proposal
With this API proposal, the solution would be greatly simplified by enclosing the entire Client component in 1 EditForm
Now each tab can determine if there are errors by calling EditContext.GetValidationMessages(address).Any()
This even works when the Tab is virtual (Meaning its contents is only instantiated when the Tab is Active) and has the added benefit that as the EditForm persists even when a Tab is deselected, as soon as the Tab is instantiated again, the errors will still be there. without needing to call Validate
on the EditContext
Risks
As this proposal adds 3 functions, without changes to the underlying Class, or API surface the risks are low.
I see a small risk for users to get confused.
For example, a user could be confused to which function the user should choose: IsModified()
or IsModified(childObject)
this could (possibly) be mitigated by changing the functions name to be more specific like IsChildModified(object childobject)
I am willing to submit a PR for this proposal if accepted.