In the past, I always thought the Model is a class closely related to the MVVM pattern... However, this is not really the case. The model should be able to send notifications or must be able to do some data mapping, but in a real-world application, the Model should be YOUR Class - perhaps implementing some interfaces if necessary.
But this is not the topic for today!
Today I want to talk about colors and other effects. Spoiler: The ViewModel has no knowledge about colors. Neither does the Model. But why do I want to set colors?
To indicate a status, of course. For example, an input is incorrect or that it is a required field. Maybe in such a case, I want to switch the background to red or show a small asterisk next to the input.
So actually I don't want to set a TEdit.Background to red, but just visualize the status.
But what about Visible and Enabled? These states could be part of the view control. Do I make an exception for this?
Sure, I think this is a good idea. Already at the beginning of my MVVM series, I said that I want to adapt the pattern to Delphi and of course to Delphi users and as I know, we all love to disable elements or set the visibility of a whole panel to false, because we need the controls on the panel just in some special reasons. We could do better, but I think I'll make this exception.
If my ViewModel belongs to a RichView, it looks different, because here all font attributes are possible, but this special case I don't mean here.
So how should I send the status to the View? I don't want to create a new label for everything. I'm thinking more about the implementation of Bootstrap or similar systems. There is no color red, it's the status warning, same as not yellow but status is hint. This status can refer to the whole View or only to one or more controls. For this, I still need a nice pattern and possibly a singleton for all views or view groups, so that you can store your own settings.
For verification I dislike the RegEx approach, I would normally call a method. Perhaps the Method is also not in the ViewModel - depends on the problem. In this case, I would trigger the ViewModel and the ViewModel could ask the Model. As everything is just a call for "get status", you can do everything you want with this. This should also be possible from a background thread (perhaps it's a REST or DB request).
I have already implemented a DeepSetter to enable the ViewModel to set everything on the View with a change event. But this was just for the proof of concept. Because if you use this kind of call, you are perhaps unable to change the View. (Bad Idea)
Let's do a list with a bind and not bind. For a TEdit - of course, you can bind to everything in code-behind or with an event-token-call, but this list is for the default bindings.
Align - not bindable
Cursor - not bindable
Enabled - bindable
Height - not bindable // But what if I have to resize the control on content?
Hint - not bindable // But perhaps connected to a translation table?
MaxLength - not bindable // Tuff desicion
Password - not bindable // Should be handled by the View (Button show PW)
ReadOnly - not bindable // Fix by design
StyleLookup - not bindable // Fix by design
Perhaps the StyleLookup is the entry point for the status info.
TabOrder - not bindable // Fix by design
Text - bindable // of course
Textprompt - good question // I will decide later
Textsettings - bindable to global Textsettings?
Visible - bindable
Width - not bindable
Now to the Onxxxx Events: (Everything could handle by the View)
OnCanFocus - good question // I will decide later
OnChange - bindable
OnChangeTracking - bindable
OnClick - not bindable // for a TEdit - a TButton would have this event.
OnDblClick - not binable
... // Skip the list of not bindable events here
OnValidate - good question // I will decide later
OnValidating - good question // I will decide later
Please Remember: For everything not bindable - this is just for the default setting. You are the Developer and if you like to screw up the pattern you could bind to everything.
So what do we have outside the MVVM Pattern?
- Enabled
- Visible
The Status is well inside the MVVM Pattern like:
- TStatus = (Valid, NotValid, Warn, Hint, Information, Mandatory) // Perhaps more?
The View could ask the StyleView-GuideLine-Singelton for display colors based on the TStatus.
That's it, are we done?
It will be a time-consuming process, but I will provide some examples with the #D.MVVM-Framework to demonstrate all these things.
I can't wait to convert my first 780.000 LOC legacy App to #D.MVVM.
Have a nice Week...
PS.: If you've made it so far - Spoiler: Next step is to open the alpha user list. If you are a Delphi 10.1.x - 10.4.x User (VCL & FMX) I will provide a link where you can submit your request.