ViewModel validations
No edit summary
No edit summary
Line 5: Line 5:
[[File:Valid -1.png|frameless|334x334px]]
[[File:Valid -1.png|frameless|334x334px]]


You will get a new row in the Validations list. Fill in the rule name, the expression that should evaluate to true when the rule is fulfilled, and false when data breaks the rule. You also provide a text with the error message you want to show.
You will get a new row in the Validations list. Fill in the rule name and the expression that should evaluate to true when the rule is fulfilled, and false when data breaks the rule. Also, provide a text with the error message you want to show.


The context of the rule is the context of the Main ViewModelClass; this means that you reach variables etc.
The context of the rule is the context of the Main ViewModelClass; this means that you reach variables etc.
Line 13: Line 13:
You can have as many rules as you need.
You can have as many rules as you need.


The rule state (true of false) can then be displayed by one or multiple columns. You right click a ViewModelColumn and check the correct rule to make an association between the two:
The rule state (true or false) can then be displayed by one or multiple columns. Right-click a ViewModelColumn and check the correct rule to make an association between the two:


[[File:Valid -4.png|frameless|482x482px]]
[[File:Valid -4.png|frameless|482x482px]]


Once the association is made and a rule break is discovered in runtime a standard WPF ValidationError will occur. How this ValidationError is displayed is defined by styles.  
Once the association is made and a rule break is discovered in runtime, a standard WPF ValidationError will occur. How this ValidationError is displayed is defined by styles.  


All these apply to the web interface.  
All these apply to the web interface.  
Line 24: Line 24:


== WPF Implementation ==
== WPF Implementation ==
In WPF, I added a default style – override it if you need – that brings up a tool tip, draws an exclamation mark behind the offending control and draws a red border around the value.
In WPF, I added a default style – override it if you need to – that brings up a tooltip, draws an exclamation mark behind the offending control, and draws a red border around the value.


The default style is defined like this:
The default style is defined like this:
Line 47: Line 47:
   </Style.Triggers>
   </Style.Triggers>
  </Style>
  </Style>
And when the rule is broken the it looks like this in runtime:
When the rule is broken, it looks like this in runtime:


[[File:Valid -5.png|frameless|423x423px]]
[[File:Valid -5.png|frameless|423x423px]]


In a view model you can add validation rules and validation rules will create messages  when some data is not properly entered.  The way you do this is you add a validation rule and name the rule.  For example here int out of range and an expression.  So here self-docked and then in this case some int roger than phi. That is the root and the message to show the int count be more than phi.  So this is a message that will show up next to this control here when I have connected  it to this control.  So you right click on some int validation rules and click on this one which will select it.  If we go back here you will see that it is now has a check mark. This some int will now show this. If we go back to the validation rules you can see that it has one column connected to  it.  So you can connect this rule to any number of controls that you want to be affected  by this.  So a more general rule could select several.   
== Validation Rules in the ViewModel ==
In a view model, you can add validation rules that will create messages when some data is not properly entered.  TAdd a validation rule and name it.  For example here int out of range and an expression. So here self-docked and then in this case some int roger than phi. That is the root and the message to show the int count be more than phi.  So this is a message that will show up next to this control here when I have connected it to this control.  Right-click on some int validation rules. Clicking on this one will select it. Verify that it now has a checkmark. This some int will now show this. If we go back to the validation rules, you can see that it has one column connected to it.  So you can connect this rule to any number of controls that you want to be affected by this.  A more general rule could select several.   


Now if you have constraints you should not repeat expressions.  Instead let's create a constraint on the thing class.  So here again not more than 5 we call it and here the value should not exceed 5 and basically  the same expression save some int roger than 5 and here we say that this is as error  level. Let's say instead this is warning level. Now we have this as a rule on the class. Each view.  So here this expression should not be here.  Instead we should use the concept of looking up if we have broken the constraint.  So let's say we take the constraint name.  Constraint name.  To this and we say instead self const range.  So this is all the constraints and we select the constraint with the name not more than  5.  And then we check if it is broken. First.  So take all the constraints.  Select the one that is not more than 5.  Then we have created.  Take the first one just to get one because we know it will only be one and check if it's broken.  And in this case it's actually the opposite.  So we need to say not broken.  So if it's not broken then it's okay.  This might seem like it's too long here.  This is more complicated than what we started with.  But it is not repeating the same thing again.  We could also take this expression and add a method to thing called check constraint valid.  Some of constraint which is a string.  And it should return a bolean.  So constraint valid name or constraint which is a string and return a bolean.  We make it a query.  Otherwise we can't use it in OCL.   
If you have constraints, you should not repeat expressions.  Instead, let's create a constraint on the thing class.  So here again not more than 5 we call it and here the value should not exceed 5 and basically the same expression save some int roger than 5 and here we say that this is an error level. Let's say instead this is warning level. Now we have this as a rule on the class. Each view.  So here this expression should not be here. We should use the concept of looking up if we have broken the constraint.  So let's say we take the constraint name.  To this and we say instead self const range.  So this is all the constraints and we select the constraint with a name no more than  5.  And then we check if it is broken. First.  So take all the constraints.  Select the one that is not more than 5.  Then we have created.  Take the first one just to get one because we know it will only be one and check if it's broken.  And in this case, it's actually the opposite.  So we need to say not broken.  So if it's not broken then it's okay.  This might seem like it's too long here.  This is more complicated than what we started with.  But it is not repeating the same thing again.  We could also take this expression and add a method to a thing called check constraint valid.  Some of constraint which is a string.  And it should return a boolean.  So constraint valid name or constraint which is a string and returns a boolean.  We make it a query.  Otherwise, we can't use it in OCL.   


And then we put the body. The body here is very similar to what we had before.  So here we take the name of constraint.  So now we're looking this up and we are returning if it's not broken.  We could also of course phrase this as maybe that's better to say that this constraint  and constraint and it's not broken.  Because then we could here say that this is empty.  So now self constraints and the name equals the name of constraint and not broken.  So we should also add here for extra protection.  Copy of that that says we should find this.  So if we just look up the name of the constraint it should not be empty.  Because we need to find the constraint to be sure that we had specified the right constraint.  And then we also should check that it's not broken.  So now we go back to the view model.  We can change this to self.com.  And then the name.  So now this is a very compact way of writing it and it can be reused over and over. If this is incorrect it's specified the whole expression will be false and we will get  notified with constant problem showing the user interface.  This is a good way to linking together constraints in the class with validations in the view model.  
Then we put the body. The body here is very similar to what we had before.  So here we take the name of the constraint.  So now we're looking this up and we are returning if it's not broken.  We could also of course phrase this as maybe that's better to say that this constraint and constraint and it's not broken.  Because then we could here say that this is empty.  Now, self constraints and the name equal the name of the constraint and are not broken.  We should also add here for extra protection.  Copy of that that says we should find this.  If we look up the name of the constraint, it should not be empty.  Because we need to find the constraint to be sure that we had specified the right constraint. We should also check that it's not broken. We go back to the ViewModel.  We can change this to self.com.  And then the name.  This is a very compact way of writing it and it can be reused over and over. If this is incorrect, it specifies that the whole expression will be false and we will get notified with constant problems showing the user interface.  This is a good way to link together constraints in the class with validations in the view model.  
[[Category:View Model]]
[[Category:View Model]]
[[Category:Validation rules]]
[[Category:Validation rules]]

Revision as of 12:19, 23 February 2023

Validations exist to enforce a set of rules that apply to a specific use case. A use case is implemented by a ViewModel, so the ViewModel needs Validations.

This is how you add them in the ViewModelEditor:

Valid -1.png

You will get a new row in the Validations list. Fill in the rule name and the expression that should evaluate to true when the rule is fulfilled, and false when data breaks the rule. Also, provide a text with the error message you want to show.

The context of the rule is the context of the Main ViewModelClass; this means that you reach variables etc.

Valid -2.png

You can have as many rules as you need.

The rule state (true or false) can then be displayed by one or multiple columns. Right-click a ViewModelColumn and check the correct rule to make an association between the two:

Valid -4.png

Once the association is made and a rule break is discovered in runtime, a standard WPF ValidationError will occur. How this ValidationError is displayed is defined by styles.

All these apply to the web interface.

(Example)

WPF Implementation

In WPF, I added a default style – override it if you need to – that brings up a tooltip, draws an exclamation mark behind the offending control, and draws a red border around the value.

The default style is defined like this:

Code Snippet

<ControlTemplate x:Key="validationTemplate">
  <DockPanel>
    <Border BorderBrush="Red" BorderThickness="2" CornerRadius="4,4,4,4"  >
      <AdornedElementPlaceholder/>
    </Border>
    <TextBlock Foreground="Red" VerticalAlignment="Center" FontWeight="ExtraBold" Margin="4">!</TextBlock>
  </DockPanel>
</ControlTemplate>

<Style TargetType="TextBox">
  <Setter Property="Validation.ErrorTemplate" Value="{StaticResource validationTemplate}">
  </Setter>
  <Style.Triggers>
    <Trigger Property="Validation.HasError" Value="true">
      <Setter Property="TextBox.ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
    </Trigger>
  </Style.Triggers>
</Style>

When the rule is broken, it looks like this in runtime:

Valid -5.png

Validation Rules in the ViewModel

In a view model, you can add validation rules that will create messages when some data is not properly entered.  TAdd a validation rule and name it.  For example here int out of range and an expression. So here self-docked and then in this case some int roger than phi. That is the root and the message to show the int count be more than phi.  So this is a message that will show up next to this control here when I have connected it to this control.  Right-click on some int validation rules. Clicking on this one will select it. Verify that it now has a checkmark. This some int will now show this. If we go back to the validation rules, you can see that it has one column connected to it.  So you can connect this rule to any number of controls that you want to be affected by this.  A more general rule could select several. 

If you have constraints, you should not repeat expressions.  Instead, let's create a constraint on the thing class.  So here again not more than 5 we call it and here the value should not exceed 5 and basically the same expression save some int roger than 5 and here we say that this is an error level. Let's say instead this is warning level. Now we have this as a rule on the class. Each view.  So here this expression should not be here. We should use the concept of looking up if we have broken the constraint.  So let's say we take the constraint name.  To this and we say instead self const range.  So this is all the constraints and we select the constraint with a name no more than  5.  And then we check if it is broken. First.  So take all the constraints.  Select the one that is not more than 5.  Then we have created.  Take the first one just to get one because we know it will only be one and check if it's broken.  And in this case, it's actually the opposite.  So we need to say not broken.  So if it's not broken then it's okay.  This might seem like it's too long here.  This is more complicated than what we started with.  But it is not repeating the same thing again.  We could also take this expression and add a method to a thing called check constraint valid.  Some of constraint which is a string.  And it should return a boolean.  So constraint valid name or constraint which is a string and returns a boolean.  We make it a query.  Otherwise, we can't use it in OCL. 

Then we put the body. The body here is very similar to what we had before.  So here we take the name of the constraint.  So now we're looking this up and we are returning if it's not broken.  We could also of course phrase this as maybe that's better to say that this constraint and constraint and it's not broken.  Because then we could here say that this is empty.  Now, self constraints and the name equal the name of the constraint and are not broken.  We should also add here for extra protection.  Copy of that that says we should find this.  If we look up the name of the constraint, it should not be empty.  Because we need to find the constraint to be sure that we had specified the right constraint. We should also check that it's not broken. We go back to the ViewModel.  We can change this to self.com.  And then the name.  This is a very compact way of writing it and it can be reused over and over. If this is incorrect, it specifies that the whole expression will be false and we will get notified with constant problems showing the user interface.  This is a good way to link together constraints in the class with validations in the view model.  

This page was edited 71 days ago on 03/12/2024. What links here