C# DataBinding del 4 – Interfaces, forretningsobjekter
For at udnytte DataBinding og især DataGridViewet fuldt ud, er det en god ide at implementere forskellige interfaces. Dels for at sikre at brugeren får en god konsistent oplevelse samtidig med at man slipper for at lave et tungt kodemæssigt arbejde i UI’en. Nedenfor har jeg listet de Interfaces som jeg har overvejet undervejs i løsningen på mine forretningsobjekter – det er ikke alle jeg er endt med at implementere, men det vil fremgå hvilke overvejelser jeg har haft med dem.
IEditableObject
Dette interface skal i de fleste tilfælde implementeres, hvis du anvender DataGrids. Det sørger for at når brugeren editerer objectet er der mulighed for at fortryde rettelserne indtil han forlader rækken (når EndEdit bliver kaldt). Det er en lækker ‘undo’-funktion som er rigtig nem at implementere. Ved BeginEdit tager man et som regel et snapshot af objectets state enten ved en fuldstændig kopi af objektet eller en array med de properties, som brugeren kan rette i. Hvis brugeren så kalder CancelEdit, giver man objektet de gamle værdier tilbage og ellers ved EndEdit tager rettelserne effekt. DataGridViewet abonnerer på dette interface, så der skal ikke gøres yderligere for at det tager effekt. Jeg har set nogle gode implementationer, hvor man ved større objekter kalder EndEdit på forskellige tidspunkter – typisk når brugeren har rettet en gruppe af properties eller når objektet validerer. Det kan især være en fordel, hvor der er rigtig store krav til samtidighed. Objekterne skal dog være forholdsvis komplekse for at det er en god ide.
IDataErrorNotify
Dette interface kan anvendes, hvis man vælger at lægge sig op af MS’ standard med hensyn til at give brugeren besked om hvilke fejl han har lavet i indtastningen. Det kan vælges i DataGridView’et hvorvidt man vil have en fejl-ikon på rækkeniveau eller kontrolniveau – og evt. begge. Interfacet betyder at kontrollerne viser et fejlikon, hvis inputtet ikke stemmer overens med reglerne angivet på den databundne property fx “Værdien skal ligge mellem 1 og 10″, når brugeren har tastet 24. Dette interface har jeg valgt at udelukke af to årsager. Da applikationen er meget indtastningstung, er det en hindring at brugeren skal have brug for musen for at finde fejlbeskeden (den ligger på hover på det røde fejl-ikon). Og samtidig virker det forvirrende for de fleste at en række bokse starter med fejl-ikon når der startes med indtastning. I et login-billede, kan det dog være meget fint, men det virker som lidt overkill at implementere interfacet blot for en så lille del af applikationen. Alle standard kontroller lytter iøvrigt på IDataErrorNotify.
INotifyPropertyChanged
Dette interface skal man have en meget god grund for ikke at implementere på objekter, der skal vises i DataGrids og især i situationer, hvor man har en oversigts- og en detailsektion. Hvis en property ændrer sig i oversigten, slår den uden dette interface ikke igennem i detail-sektionen og vice-versa. Først i det øjeblik kontrollen får fokus vil værdien opdateres. Det samme gør sig gældende hvis objektet bliver ændret andetsteds fra (fx via en knap el. lign.) Her vil INotifyPropertyChanged sørge for at evt. bunde kontroller bliver opdateret.
IComparable
Dette interface har betydning for hvordan (og om) objektet bliver sorteret. Lad os sige vi har en række i et DataGridView med bookinger – i et af felterne vises et objekt (fx kunden). Hvis man så sorterer på denne kolonne, vil resultatet blive ‘underligt’ uden dette interface, da det ikke er specificeret hvad der skal sorteres på. I de fleste tilfælde vil det være en god ide at sortere på .ToString(), da det er den værdi der vises i DataGridViewet (og det virker mest intuitivt at sortere på det viste).