-
Notifications
You must be signed in to change notification settings - Fork 688
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: Suggested input validation architecture for WinUI with MVVM #5859
Comments
@Mohamed1984 I recommend thinking about how this would be expressed in WinRT, not C#, since these features need to work across languages. ref: https://docs.microsoft.com/en-us/uwp/winrt-cref/winrt-type-system#parameterized-interfaces
|
IMO, WinUI should just provide UI for validation and do not impose restrictions on validation logic. Such logic could be provided by third-party and open-source frameworks like Windows Toolkit. |
@Mohamed1984 there's the existing There are other things building on top of this already like the ObservableValidator helper in the MVVM Toolkit that work for both WPF and WinUI 3 already. |
Also see discussions in #179. |
I have no thorough knowledge of WinRT. But i think the solution may be based on source generation tools. |
Proposal: Suggested input validation architecture for WinUI with MVVM
Summary
Simpler input validation architecture than that based on INotifyPropertyChanged interface
Rationale
Input validation of WinUI is not yet stabilized. Hence, there is a chance for improving the architecture. The proposed input validation based on INotifyPropertyChanged interface is lacking the (form validation) feature and puts a big burden on the programmer to unnecessarily manage and store errors. A better approach is desired that is easy to implement, configurable, and satisfy all user needs.
Before i present the details of my proposal let me abstract the input validation task into three levels of complexity:
Isolated property validation
In this simple kind of validation, we are interested in validating the input based only on the user input value. The validation is independent from other property values or any other state.
Validation using property annotation is enough for this kind of validation. The programmer need only annotate the viewmodel properties with desired validation rules.
Contextual property validation
In this kind of validation, the validation logic of a property depends on other state than its own value. Consider for example the verification that user name written in a text field is unique. This may require sending a request to a web server to verify the uniqueness of the name.
Form validation
In some circumstances, the form state may be invalid even if all input fields are valid. This may happen if the input fields values are not consistent in some way that depends on business logic. Such kind of validation can be implemented after the user clicks the submit button, but it may be beneficial to do the form validation logic as the user input data.
Proposed approach
The programmer should be able to select one of the three validation levels he thinks suitable for him. Let's consider how each approach may be implemented.
Isolated property validation
This should simply be enabled whenever the view model (or page/window) implements some interface such as IValidatable
The IValidatable is a generic interface that takes the view model class type as argument. The UI part should inspect the view model object for IValidatable interface and correspondingly respond to PropertyChanged event by checking for property validation annotations and doing validation stuff. The validation errors need not be propagated to the view model.
The input control should have some Errors property that contains the validation errors.
Contextual property validation
Another option for the programmer is to implement contextual property validation approach. The view model should implement the IPropertyValidatable interface.
The method ValidateProperty should be called by the UI whenever propertyChanged event is fired. The method is asynchronous to allow for asynchronous validations (for example making sure that user name is unique).
The validation context gives enough information about other validation state, this may be useful during the contextual property validation.
The GetPropertyValidationState method returns validation state of other properties, it is possible that some input field didn't receive any user input yet, hence the corresponding property validation state should be undetermined.
Form validation
Form validation is an extension of contextual property validation that handles these cases:
Form validation can be implemented when the user implements the IFormValidatableInterface
The logic for invokation of ValidateForm method should be as follows:
The form validation state can be easily stored in the viewmodel using the validateForm method.
Unlike the ValidateProperty method, there is no undetermined input state, all properties are always checked from the beginning.
The FormValidationContext have methods to register property errors or global form errors. It can also provide validation state about any property or InputState (i.e. whether the user input any data in the field or not).
Interaction with PropertyChanged event
In validation based on INotifyPropertyChanged, the invokation of validation is the responsibility of the viewmodel designer in the property set methods. I think this is unnecessary complication. The UI should respond to PropertyChanged event and call the ValidateProperty correspondingly.
The text was updated successfully, but these errors were encountered: