En textbox har et Validating event, med dette kan vi samme med en errroprovider checke input:

Relaterede dokumenter
Tredjepart webservices

Databaseadgang fra Java

AAU, Programmering i Java Intern skriftlig prøve 18. maj 2007

SWC eksamens-spørgsmål. Oversigt

Programmering I Java/C#

F# - hvorfor, hvordan og til hvad? Rune Ibsen Jyske Bank

MS Visual Studio Basic En kort vejledning

Eksempel: et ordresystem note 5 Lagdeling s. 1

Hvordan vælger jeg dokumentprofilen?

Eksamens spørgsmål Software Construction. Objekter. Spørgsmål 1: Januar Giv en beskrivelse af Objekt-begrebet og deres brug

Specifikation Abstrakt OO OS-API Rev Specifikation. Abstrakt, objektorienteret operativsystem-api

Videregående Programmering Obligatorisk opgave - 3. semester, efterår 2004

Projekt - Visual Basic for Applications N på stribe

Software Construction 1 semester (SWC) Spørgsmål 1

Øvelse 9. Klasser, objekter og sql-tabeller insert code here

Test af It-komponent

DANMARKS TEKNISKE UNIVERSITET

//Udskriver System.out.println("Hej " + ditfornavn + " " + ditefternavn + "."); System.out.println("Du er " + dinalder + " aar gammel!

Indledning. Hvorfor det forholder sig sådan har jeg en masse idéer om, men det bliver for meget at komme ind på her. God fornøjelse med læsningen.

Kursusarbejde 3 Grundlæggende Programmering

Kapitel 4 Løkker i C#

University of Southern Denmark Syddansk Universitet. DM502 Forelæsning 3

Udvikling af DOTNET applikationer til MicroStation i C#

1 Domæne Design valg User Klassediagran 5

Rapport. Udarbejdet af: Mayianne Nøks Pedersen. Skole login: knmape68.

PHP Snippets. De små korte. Skrevet af Daniel Pedersen

Umbraco installationsvejledning

DMX styring med USB-interface

PROGRAM. using System; using System.Collections.Generic; using System.Text; using System.Collections;

Kapitel 1 I gang med C#

University of Southern Denmark Syddansk Universitet. DM503 Forelæsning 11

SAX Simple API for XML.

3. PROJEKT, 2 SEMESTER

University of Southern Denmark Syddansk Universitet. DM502 Forelæsning 2

Skriftlig eksamen i Datalogi

PHP 3 UGERS FORLØB PHP, MYSQL & SQL

Programmering for begyndere Lektion 2. Opsamling mm

Skriftlig eksamen i Datalogi

Specifikationsdokument for PDF Validator API

Brugervejledning - Kundeportal kiropraktor

Zapier-integration mellem MailChimp og webcrm hos Azalea IT

Anvendelse af metoder - Programmering

DRONNINGER (QUEENS) Opgave 1

UC Syddanmark

SQL Server Express og C#

C# spil (del 1) - Kom i gang med et simpelt spil

Under 'Microsoft Block Editor', klik 'New project' for at åbne block editor-værktøjet.

Hent filoplysninger fra billeder og filer

HUMANWARE BRAILLIANT INSTALLATIONSVEJLEDNING

Skype Guide. Indholdsfortegnelse

ExtraNet. Sider beskyttet med kodeord i OLO

Brugermanual til Assignment hand in

Kapitel 3 Betinget logik i C#

Specifikationsdokument for PDF Validator API

Privat-, statslig- eller regional institution m.v. Andet Added Bekaempelsesudfoerende: string No Label: Bekæmpelsesudførende

Undtagelseshåndtering i C#

MySQL i Java. Tutorial lavet af Jákup W. Hansen TSU semester 05.januar 2007

Videregående programmering i Java

I denne manual kan du finde en hurtig introduktion til hvordan du:

Introduktion til ActionScript

sådan gør du... [meld dig ledig]

TDC Erhverv Cloud Storage. Brugermanual. EMC² CIFS-ECS Ver August 2016

Installation af Bilinfo på Windows

Web- og serverprogrammering

Andreas Nordbek & Kristoffer Skude Jensen. DMX Styring Side 1 af 15

Indholdsfortegnelse If-sætningen... 3 Opgaver... 4 OR, AND sammen med if-sætningen... 5 Rand() funktion... 5 Opgave... 5 Include() funktionen...

Transkript:

Inputvalidering i Windows Forms Applikationer Rolf Therkildsen (6. nov 2008) Krav til inputvalidering Brugeren må aldrig blive forhindret i at flytte til en anden kontrol. Brugeren skal informeres om fejl via ErrorProvider kontrollen. Generelt Lige et eksempel vi kan snakke om (to tekstbokse, en knap er en errorprovider): En textbox har et Validating event, med dette kan vi samme med en errroprovider checke input: private void txtname_validating(object sender, CancelEventArgs e) ValidateName(); private bool ValidateName() if (!Customer.isNameValid(txtName.Text)) errorprovider1.seterror(txtname, "Please type a name."); return false; errorprovider1.seterror(txtname, ""); return true; Der er to problemer med dette. Eventet bliver ikke kaldt hvis ikke brugeren har været i feltet, og selvom der er fejl, bliver koden bag OK-knappen stadig kørt. For at løse dette bliver man, som det første koden bag OK-knappen, nød til at teste at alt er ok. private void button1_click(object sender, System.EventArgs e) bool validname = ValidateName(); bool validage = ValidateAge(); if (validname && validage) MessageBox.Show("Ok"); MessageBox.Show("Error");

Dette er fjollet. I stedet for dette så lad os spørge errorprovideren i stedet. Desværre ved den ikke om der er nogen fejl på siden. Men det gør vi noget ved. En kontrol kalder Evaluate-eventet når den midste focus. Så hvis vi sætter fokus til alle kontroller og derefter sætter fokus et andet sted sker der en evaluering. ErrrorProvideren kan spørges om en kontrol har fejlet. Så hvis man løber alle kontroller igennem ved man også om der er fejl på formen. Dette har jeg samlet i classe, som nedarver fra ErrorProvider. Download fra http://www.rolft.dk/programs/inputvalidation/inputvalidation.zip. Man kan nu gøre således: private void button1_click(object sender, EventArgs e) if (extendederrorprovider1.isvalid()) MessageBox.Show("Ok"); MessageBox.Show("Error"); En mindre krølle er kontroller, som selv viser fejlmeddelr. F.esk. DataGridView:

Disse fortæller jo ikke ErrorProviderren om deres eventuelle fejl. Dette løses ved at implementerer Validation eventet på controllen alligevel og kalde SetHiddenError, som er en funktion som jeg har tilføjet til ErrorProvideren. Funktionen gemmer bare fejlen i intern liste. private void dgvcustomers_validating(object sender, CancelEventArgs e) foreach (DataGridViewRow row in dgvcustomers.rows) foreach (DataGridViewCell cell in row.cells) if (cell.errortext.length == 0) extendederrorprovider1.sethiddenerror(dgvcustomers, "Some values in the grid has errors."); return; extendederrorprovider1.sethiddenerror(dgvcustomers, ""); Inputvalidering i DataGridView Hvis man har en regel for, hvad brugeren må indtaste i en celle, så checkes dette bedst via CellValidating eventet på grid et og brug cellens ErrorText til at marker, hvis der er fejl. F.eks.: private void grid_cellvalidating(object sender, DataGridViewCellValidatingEventArgs e) DataGridView grid = (DataGridView) sender; if (e.columnindex==1) if (!Customer.isNameValid((string)e.FormattedValue)) grid.rows[e.rowindex].cells[e.columnindex].errortext = "Wrong name"; grid.rows[e.rowindex].cells[e.columnindex].errortext = ""; Hvis et check indeholder vædier fra flere kolonner, så brug RowValidating i stedet. Hvis ovenstående skal virke, kræver det dog at det databærende objekt kan indeholde den fejlagtige værdi. Indtaster man f.eks. et bogstav ind i id-kolonnen, som er af typen int, får man en DataGridView Default Error

Dialog op med et staktrace. Samtidig kan man ikke forlade feltet, før man har tastet en rigtig værdi. Dette er ikke en acceptabel opførsel. Dette løses via de to CellParsing og CellFormatting events. I CellParsing eventet prøver man at lave konverteringen. Hvis dette går galt, gemmer man fejlinputtet i et 2D array (her kaldet inputwitherror), sætter ErrorText på cellen og gemmer den tidligere værdi i det underliggende databærende objekt: private void grid_cellparsing(object sender, DataGridViewCellParsingEventArgs e) try //Try to convert e.value = Convert.ChangeType(e.Value, e.desiredtype); Rows[e.RowIndex].Cells[e.ColumnIndex].ErrorText = ""; inputwitherror.delete(e.columnindex, e.rowindex); catch (FormatException exp) //Save the input for later display inputwitherror.put(e.columnindex, e.rowindex, e.value); //Put the existing value into the underlaying data container e.value = Rows[e.RowIndex].Cells[e.ColumnIndex].Value; Rows[e.RowIndex].Cells[e.ColumnIndex].ErrorText = exp.message; e.parsingapplied = true; I CellFormatting kan vi nu sørge for, at fejlinputtet stadig bliver præsenteret i stedet for, hvad der nu ligger i det underliggende databærende objekt. private void grid_cellformatting(object sender, DataGridViewCellFormattingEventArgs e) if (inputwitherror.has(e.columnindex, e.rowindex)) e.formattingapplied = true; e.value = inputwitherror.get(e.columnindex, e.rowindex);

Jeg har lavet en klasse som nedarver fra DataGrivView som implementerer ovenstående. Dette kan findes på http://www.rolft.dk/programs/inputvalidation/inputvalidation.zip. Det går dog stadig galt, hvis det databærende objekt smider en exception (andre end FormatException). F.eks.: public string Name get return name; set if (!isnamevalid(value)) throw new ArgumentException("Name is invalid", Name); name = value; Men det må du selv overveje. Begræns input til tekstbokse En gang imellem er det nemmere at sikre, at brugeren ikke taster noget forkert, end at skulle tjekke senere. Ønsker man f.eks. et positivtheltal fra brugeren, er der ikke nogen grund til, at han kan taste bogstaver ind i tekstboksen. Dette kan gøres ved at abonere på tekstboksens KeyDown event. F.eks.: void NumberTextBox_KeyDown(object sender, KeyEventArgs e) //Supress all key strokes e.suppresskeypress = true; if ((e.keycode >= Keys.NumPad0 && e.keycode <= Keys.NumPad9) (e.keycode >= Keys.D0 && e.keycode <= Keys.D9)) //Except 0 to 9 e.suppresskeypress = false; if (e.keycode == Keys.Back e.keycode == Keys.Delete) //Except delete e.suppresskeypress = false; if (e.keycode == Keys.Left e.keycode == Keys.Right e.keycode == Keys.End e.keycode == Keys.Home)

//Except moving keys e.suppresskeypress = false; Jeg har lavte et eksempe på dette kaldet en NumberTextBox. Den nedarver fra TextBox men begrænser input til hel- eller decimaltal.