Αναλυτικά Data Validation FORM LEVEL VALIDATION - DATA LEVEL VALIDATION - επίπεδο φόρμας επίπεδο dataset 1. ΕΛΕΓΧΟΙ ΕΓΚΥΡΟΤΗΤΑΣ ΣΕ ΜΙΑ ΦΟΡΜΑ Έλεγχος εγκυρότητας δεδοµένων σε ένα Control της φόρµας event Validating για έλεγχο εισαγωγής σωστών δεδοµένων property Cancel = true - προτρέπει τον χρήστη να ξαναδώσει σωστά δεδοµένα - µη δινοντάς του την δυνατότητα να αφήσει το control property CancelEventArgs Όταν κλείνει µια φόρµα event FormClosing για έλεγχο της εγκυρότητας των δεδοµένων και προτροπή στον χρήστη να σώσει Aλλαγές σε πίνακα Η µέθοδος GetChanges σε ένα πίνακα, επιστρέφει τις γραµµές του πίνακα µε τις αλλαγές ή Nothing αν δεν υπάρχουν Έλεγχος σωστής εισαγωγής (όχι κενό, δεκαδικός θετικός αριθμός) στην φόρμα Products.vb για το Textbox με όνομα UnitPriceTextBox για το event Validating: (All event handlers in VB 2008 pass two arguments to the application: the sender argument, which is an object that represents the control that fired the event, and the e argument, which provides additional information about the event.) Private Sub UnitPriceTextBox_Validating( ByVal sender As Object,ByVal e As _ System.ComponentModel.CancelEventArgs) Handles UnitPriceTextBox.Validating If UnitPriceTextBox.Text = String.Empty OrElse Not _ Decimal.TryParse(UnitPriceTextBox.Text, 0D) Then 0Decimal MessageBox.Show("Please enter a price", "Products", _ MessageBoxButtons.OK, MessageBoxIcon.Error) Return If Convert.ToDecimal(UnitPriceTextBox.Text) <= 0 Then MessageBox.Show("Price must be higher than 0", "Products", _ MessageBoxButtons.OK, MessageBoxIcon.Error) [1]
e: το event validating cancel = true : δεν θα ολοκληρωθεί Έλεγχος σωστών δεδομένων σε μια οποιαδήποτε φόρμα π.χ. στην φόρμα με όνομα DataValidation γίνεται με το event FormClosing όταν κλείνουμε την φόρμα χωρίς να πατηθεί το SAVE. 1 Private Sub DataValidation_FormClosing(ByVal sender As System.Object, ByVal e As _ System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing If ValidateData() Then If Me.NorthwindDataSet.Products.GetChanges IsNot Nothing Then Dim response As Integer response =MessageBox.Show("Do you want to save your changes?", _ "Changes have been made", _ MessageBoxButtons.YesNoCancel,MessageBoxIcon.Warning) If response = DialogResult.Yes Then If SaveChanges() Then MessageBox.Show("Your changes were saved", "Products", _ MessageBoxButtons.OK) Else ElseIf response = DialogResult.Cancel Then 1 Αυτή η μέθοδος πρέπει να υπάρχει πάντα και σε επίπεδο data form και σε επίπεδο dataset [2]
Ελεγχος της τελευταίας εισαγωγής (πριν το κλείσιµο της φόρµας) Private Function ValidateData() As Boolean If Me.Validate() Then Try Me.ProductsBindingSource.EndEdit() Catch ex As Exception If MessageBox.Show( _ "Invalid data was entered. Cancel edits?", _ "Products", MessageBoxButtons.YesNo, _ MessageBoxIcon.Error) = DialogResult.Yes Then ProductsBindingSource.CancelEdit() End Try End Function Αν ο χρήστης επιλέξει να σώσει τις αλλαγές του γίνεται συνδυαστικός έλεγχος π.χ. για προϊόντα µε τιµές >25$ πρέπει η επαναπαραγγελία <100 Private Function SaveChanges() As Boolean If ValidateData() Then If ReorderLevelTextBox.Text <> String.Empty Then If Convert.ToDecimal( _ UnitPriceTextBox.Text) > 25 And _ Convert.ToInt32( _ ReorderLevelTextBox.Text) > 100 Then MessageBox.Show( _ "Products that cost more than $25 " & _ "must have a reorder level below 100", _ "Products", MessageBoxButtons.OK, _ MessageBoxIcon.Information) Me.TableAdapterManager.UpdateAll( Me.NorthwindDataSet) End Function Όµως οι έλεγχοι αυτοί πρέπει να επαναλαµβάνονται κάθε φορά που ένα πεδίο βρίσκεται σε άλλη φόρµα! Λύση -> Να γίνεται ο έλεγχος στο DATASET, χρησιµοποιώντας τα events των DataTable [3]
2. ΕΛΕΓΧΟΙ ΕΓΚΥΡΟΤΗΤΑΣ ΣΕ ΕΠΙΠΕΔΟ DATASET DataTable events: ColumnChanging - update µιας στήλης RowChanging - update µιας γραµµής TableNewRow προσθήκη µιας νέας γραµµής DataTable properties: Κάθε πίνακας έχει την ΗasErrors property. Κάθε γραµµή- εγγραφή ενός πίνακα έχει την RowError property. ΕrrorProvider πάνω στην φόρµα Στο αρχείο NorthwindDataSet.vb 2 που είναι η Partial Class NorthwindDataSet, θα πρέπει να υπάρχει µέσα µια Partial Class για κάθε πίνακα π.χ. για τον πίνακα Products η Partial Class ProductsDataTable Partial Class NorthwindDataSet Partial Class ProductsDataTable Private Sub ProductsDataTable_ColumnChanging(ByVal sender As Object, _ ByVal e As System.Data.DataColumnChangeEventArgs) _ Handles Me.ColumnChanging If e.column.columnname = "UnitPrice" Then If Convert.ToDecimal(e.ProposedValue) <= 0 Then e.row.setcolumnerror(e.column, _ "Please enter a price greater than $0.") Else e.row.setcolumnerror(e.column, String.Empty) Private Sub ProductsDataTable_ProductsRowChanging (ByVal sender As _ Object, ByVal e As ProductsRowChangeEvent) Handles e.productsrowchanging If e.row.rowstate <> DataRowState.Deleted Then If e.row.unitprice > 25 And e.row.reorderlevel > 100 Then e.row.rowerror ="Products that cost more than $25 must " & _ "have a reorder level below 100" Else e.row.clearerrors() 2 Ανοίγοντας το NorthwindDataSet.xsd δεξί κλικ και ViewCode έχω την Partial Class NorthwindDataSet [4]
Private Sub ProductsDataTable_TableNewRow(ByVal sender As Object, _ ByVal e As System.Data.DataTableNewRowEventArgs) Handles _ Me.TableNewRow Dim productrow As NorthwindDataSet.ProductsRow = _ CType(e.Row, NorthwindDataSet.ProductsRow) productrow.discontinued = False End Class Βάζοντας τον ΕrrorProvider πάνω στην φόρµα Κάθε πίνακας έχει την ΗasErrors property. Κάθε γραµµή- εγγραφή ενός πίνακα έχει την RowError property. Mέσα στην φόρµα Products µπορούν να υπάρχουν και οι κάτωθι συναρτήσεις: Private Function DataHasErrors() As Boolean Dim errorstring As New System.Text.StringBuilder If Me.NorthwindDataSet.Products.HasErrors Then For Each row As DataRow In Me.NorthwindDataSet.Products If row.haserrors Then errorstring.append(row.rowerror & vbcrlf) Next MessageBox.Show("The following errors occurred: " & vbcrlf & _ vbcrlf & errorstring.tostring, "Products", _ MessageBoxButtons.OK, MessageBoxIcon.Error) [5]
End Function Private Function SaveChanges() As Boolean If ValidateData() Then 'είναι η ίδια µέθοδος µε πριν, σελίς 3 If Not DataHasErrors() Then Me.TableAdapterManager.UpdateAll( Me.NorthwindDataSet) End Function Τότε ο αρχικός κώδικας του Save button µε τις τρεις µεθόδους: Validate, EndEdit και UpdateAll, (Private Sub ProductsBindingNavigatorSaveItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ProductsBindingNavigatorSaveItem.Click Me.Validate() Me.ProductsBindingSource.EndEdit() Me.TableAdapterManager.UpdateAll(Me.NorthwindDataSet) ) Save Button θα αντικατασταθεί µε την function SaveChanges: Private Sub ProductsBindingNavigatorSaveItem_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles ProductsBindingNavigatorSaveItem.Click If SaveChanges() Then MessageBox.Show("Your changes were saved", "Products", MessageBoxButtons.OK) [6]