📜 ⬆️ ⬇️

Validating Forms in a Declarative Style (C #)

I think many of you have faced the challenge of validating data in forms. It is long, tedious and often requires considerable effort. Sometimes it seems to me that the guys from Redmont mock us, offering to carry out validation so . Just kidding, of course, but we will not use this method.

We will validate the form data automatically, using the rules described in the declarative style. Take the simplest form:



There are several regular text fields, a number input field and an e-mail field. Let's set the following rules for our form:
')
Fields last name, first name and patronymic must be filled with at least one printed (not whitespace) symbol:
txtSurname .ValidateControl() .IsNotNullOrWhitespace(); txtName .ValidateControl() .IsNotNullOrWhitespace(); txtMiddleName .ValidateControl() .IsNotNullOrWhitespace(); 


Age must be at least 16 years. If the specified age is less than 21 years, you must display a warning, but allow the form to be saved:
 nmAge .ValidateControl() .IsTrue(ctl => ctl.Value >= 16, "     16 .", ValidationType.Required) .IsTrue(ctl => ctl.Value >= 21, "  (21+)    .", ValidationType.Optional); 


The e-mail field must be filled with the correct value (or at least similar to the e-mail):
 txtEMail .ValidateControl() .IsValidEMail(false); 


If all fields are filled in correctly, allow the “Save” button to be pressed, otherwise not:
 butSave .ValidateControl() .EnableByValidationResult(); 


Class code form one sheet
 public partial class frmMain : Form { public frmMain() { InitializeComponent(); // ,     txtSurname .ValidateControl() .IsNotNullOrWhitespace(); txtName .ValidateControl() .IsNotNullOrWhitespace(); txtMiddleName .ValidateControl() .IsNotNullOrWhitespace(); //     16  //     (    )  21  nmAge .ValidateControl() .IsTrue(ctl => ctl.Value >= 16, "     16 .", ValidationType.Required) .IsTrue(ctl => ctl.Value >= 21, "  (21+)    .", ValidationType.Optional); //      e-mail'    txtEMail .ValidateControl() .IsValidEMail(false); //     /   butSave .ValidateControl() .EnableByValidationResult(); } } 



What do we get when we run the form? First: we will get a convenient highlighting of each field, the value of which is filled with incorrect data. Secondly: if you move the mouse cursor to the indicator, we will see what the form wants from us:



Thirdly: the “Save” button will be available for pressing only after successful data validation.

Well, with a simple form, we figured out, but what about the form more complicated? Let's complicate the task. Let's make an improvised search form for articles for Habr:



We have three filters, the selection of which should activate the checks for the specified conditions for each filter. Plus activation controls that belong to the selected filter. I would like to note that managing the state of controls does not really relate to data validation, but in this case we will not focus on this.

Activating the controls will do so:
 //     var categoryCheckBoxes = pnlCategories.Controls.Cast<CheckBox>(); //         dtBegin.EnableByTimer(() => chkFilterByDate.Checked); dtEnd.EnableByTimer(() => chkFilterByDate.Checked); pnlCategories.EnableByTimer(() => chkFilterByCategory.Checked); pnlTextFilter.EnableByTimer(() => chkFilterByText.Checked); 


Now the validation rules. If the filter by date is enabled, then the start date must be less than or equal to the final one. The start date cannot be earlier than 1990. Validation will occur in both DatePickers, but the display will only be displayed on dtEnd:
 dtEnd .ValidateControl() .IsTrue(ctl => !chkFilterByDate.Checked || dtBegin.Value >= new DateTime(1990, 1, 1), "       1990 ") .IsTrue(ctl => !chkFilterByDate.Checked || dtBegin.Value <= dtEnd.Value, "       "); 


If filtering by category is performed, then at least one category must be selected:
 pnlCategories .ValidateControl() .IsTrue(ctl => !chkFilterByCategory.Checked || categoryCheckBoxes.Any(c => c.Checked), "  "); 


If you search for text, you must specify the text and select where to find it:
 pnlTextFilter .ValidateControl() .IsTrue(ctl => !chkFilterByText.Checked || chkSearchTextInBody.Checked || chkSearchTextInHeader.Checked, "    ") .IsTrue(ctl => !chkFilterByText.Checked || !string.IsNullOrWhiteSpace(txtSearchText.Text), "  "); 


Also, for successful validation of the form, at least one of the filters must be specified for the search:
 gbSearchParameters .ValidateControl() .IsTrue(ctl => chkFilterByCategory.Checked || chkFilterByDate.Checked || chkFilterByText.Checked, "   ."); 


Well, according to the results of form validation, we activate the main active button:
 butSearch .ValidateControl() .EnableByValidationResult(); 


Full code of the second form
 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using Teleavtomatika.Forms; namespace Teleavtomatika_Form_Validation { public partial class frmMain2 : Form { public frmMain2() { InitializeComponent(); //     var categoryCheckBoxes = pnlCategories.Controls.Cast<CheckBox>(); //         dtBegin.EnableByTimer(() => chkFilterByDate.Checked); dtEnd.EnableByTimer(() => chkFilterByDate.Checked); pnlCategories.EnableByTimer(() => chkFilterByCategory.Checked); pnlTextFilter.EnableByTimer(() => chkFilterByText.Checked); //   : //     ,          //       1990  //      DatePicker',       dtEnd dtEnd .ValidateControl() .IsTrue(ctl => !chkFilterByDate.Checked || dtBegin.Value >= new DateTime(1990, 1, 1), "       1990 ") .IsTrue(ctl => !chkFilterByDate.Checked || dtBegin.Value <= dtEnd.Value, "       "); //      //        pnlCategories .ValidateControl() .IsTrue(ctl => !chkFilterByCategory.Checked || categoryCheckBoxes.Any(c => c.Checked), "  "); //     //     //      pnlTextFilter .ValidateControl() .IsTrue(ctl => !chkFilterByText.Checked || chkSearchTextInBody.Checked || chkSearchTextInHeader.Checked, "    ") .IsTrue(ctl => !chkFilterByText.Checked || !string.IsNullOrWhiteSpace(txtSearchText.Text), "  "); //    -      gbSearchParameters .ValidateControl() .IsTrue(ctl => chkFilterByCategory.Checked || chkFilterByDate.Checked || chkFilterByText.Checked, "   ."); //           "": butSearch .ValidateControl() .EnableByValidationResult(); } } } 



You can see how it works live on video:


Sources here.

Source: https://habr.com/ru/post/209820/


All Articles