{"id":55000067,"date":"2016-12-01T00:00:00","date_gmt":"2020-03-27T19:23:54","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=67"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"EDM_Validieren_von_Entitaeten_mit_IDataErrorInfo","status":"publish","type":"post","link":"https:\/\/vbentwickler.de\/EDM_Validieren_von_Entitaeten_mit_IDataErrorInfo\/","title":{"rendered":"EDM: Validieren von Entit&auml;ten mit IDataErrorInfo"},"content":{"rendered":"<p><b>Die Validierung bei der Eingabe von Daten ist eines der wichtigsten Themen bei der Erstellung benutzerfreundlicher Anwendungen. Nachdem der Artikel &#8220;EDM: Ausnahmen beim Speichern behandeln&#8221; gezeigt hat, wozu Sie im Rahmen der Validierung die durch Restriktionen im Datenmodell auftretenden Exceptions nutzen k&ouml;nnen, schauen wir uns nun einen einfachen Weg an, um Validierungsregeln in Entit&auml;tsklassen zu definieren und beim Fehlschlagen der Validierung entsprechende Meldungen in der Benutzeroberfl&auml;che auszugeben. Dabei zeigen wir hier den Umgang mit der Schnittstelle &#8220;IDataErrorInfo&#8221;.<\/b><\/p>\n<h2>Beispielanwendung<\/h2>\n<p>Wie im oben genannten Artikel nutzen wir wieder die Beispielanwendung <b>Bestellverwaltung<\/b>. Bevor die im Datenmodell dieser Anwendung festgelegten Restriktionen greifen und bei Fehleingaben Exceptions ausl&ouml;sen, wollen wir Validierungen programmieren, um Fehleingaben des Benutzers zu vermeiden. In diesem Fall schauen wir uns die Seite <b>Kundendetails.xaml.cs <\/b>an, um die Programmierung der Validierung zu veranschaulichen. Dies soll im Ergebnis wie in Bild 1 aussehen.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2016_06\/pic_67_001.png\" alt=\"Beispiel f&uuml;r eine einfache Validierungsmeldung\" width=\"499,6607\" height=\"433,1696\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Beispiel f&uuml;r eine einfache Validierungsmeldung<\/span><\/b><\/p>\n<h2>Validierung<\/h2>\n<p>Die hier vorgestellten Techniken zur Validierung von Benutzereingaben beziehen sich auf die Untersuchung der jeweiligen Entit&auml;t &#8211; ist ein Wert in einem Feld mit einem eindeutigen Index bereits vorhanden Darf ein Feld &uuml;berhaupt leer sein Hat der Benutzer auch ein g&uuml;ltiges Datum eingegeben Liegt der Zahlenwert im zul&auml;ssigen Bereich<\/p>\n<h2>Validierung auf Feldebene<\/h2>\n<p>Validierungen k&ouml;nnen Sie auf mehrere Arten durchf&uuml;hren. Der Artikel EDM: Ausnahmen beim Speichern behandeln zeigt, wie Sie erst beim Auftreten von Fehlern beim Speichern auf fehlerhafte Eingaben des Benutzers reagieren k&ouml;nnen. Davor gibt es noch mindestens zwei weitere Methoden:<\/p>\n<ul>\n<li>Validieren direkt nach der Eingabe eines Wertes in ein Steuerelement und Hinweis auf die fehlerhafte Eingabe<\/li>\n<li>Validieren, nachdem der Benutzer den Speichervorgang initiiert hat, aber bevor das Speichern selbst stattfindet. Hier k&ouml;nnen dann nicht nur einzelne Felder isoliert, sondern auch mehrere Felder im Zusammenhang untersucht werden. Wie dies gelingt, zeigt zum Beispiel der Artikel EDM: Validieren von Entiten mit IValidatableObject. <\/li>\n<\/ul>\n<p>In diesem Artikel schauen wir uns die einfachere Validierung direkt nach der Eingabe eines Wertes an.<\/p>\n<p>F&uuml;r den Benutzer hat dies beispielsweise den Vorteil, dass er Fehleingaben direkt erkennt und diese direkt korrigieren kann.<\/p>\n<h2>Einfache Validierung<\/h2>\n<p>In vielen F&auml;llen reicht eine einfache Validierung der Eingaben f&uuml;r Steuerelemente aus. Damit meinen wir, dass nur die Werte einzelner Steuerelemente gepr&uuml;ft werden sollen, und zwar direkt nach der Eingabe. So k&ouml;nnen Sie beispielsweise abfragen, ob ein Wert eine bestimmte Mindestl&auml;nge erreicht, und bei Nichterf&uuml;llung dieser Vorgabe einen optischen Hinweis einblenden. Dieser Artikel zeigt, wie Sie eine solche Validierung zu einer Anwendung hinzuf&uuml;gen k&ouml;nnen.<\/p>\n<h2>Beispielanwendung<\/h2>\n<p>Die Beispielanwendung hei&szlig;t Bestellverwaltung. Die im Fenster MainWindow eingeblendete Seite Kundendetails.xaml soll zeigen, wie Sie die hier vorgestellte Art der Validierung implementieren.<\/p>\n<h2>Ablauf der Validierung<\/h2>\n<p>Die Validierung mit der hier vorgestellten Methode geschieht immer gleich nach dem Abschluss der Eingabe in ein Feld. Sie l&ouml;st dann die Anzeige des Steuerelements mit der fehlerhaften Eingabe mit rotem Rahmen und mit einem Warnsymbol aus. Das &Uuml;berfahren des Warnsymbols mit der Maus f&uuml;hrt zur Anzeige eines ToolTip-Textes, der weitere Informationen zum vorliegenden Fehler liefert.<\/p>\n<h2>Aufbau der Validierung<\/h2>\n<p>Die Validierung basiert auf zwei verschiedenen Elementen. Das erste Element ist die Klasse, welche die Entit&auml;t der zu validierenden Objekte beschreibt, in unserem Fall also etwa Kunde.cs. Hier legen wir in Form einer Methode die Regeln fest, nach denen das soeben ge&auml;nderte Steuerelement gepr&uuml;ft werden soll. Damit erhalten wir eine Basis, die wir f&uuml;r alle Zugriffe auf Objekte dieser Klasse nutzen k&ouml;nnen, was die Wiederverwendbarkeit dieser Klasse erh&ouml;ht. Der zweite Teil der Validierung ist das Hinzuf&uuml;gen einer bestimmten Eigenschaft zum Binding des Steuerelements, im Falle eines Textfeldes also beispielsweise zum Attribut Text. Au&szlig;erdem m&uuml;ssen wir noch definieren, wie sich das Aussehen des Textfeldes &auml;ndern soll, wenn die Validierung fehlgeschlagen ist. Immerhin wollen wir den Benutzer ja auch informieren, wenn dieser eine Fehleingabe t&auml;tigt. Dies erledigen wir durch eine entsprechende Vorlage f&uuml;r das TextBox-Steuerelement. Schauen wir uns nun die drei Elemente der Validierung an.<\/p>\n<h2>Anpassen der Klasse Kunde.cs<\/h2>\n<p>Unser Entity Data Model, das wir auf Basis der SQL Server-Datenbank Bestellverwaltung erstellt haben, enth&auml;lt auch eine Klasse namens Kunde.cs, welche die Eigenschaften eines Kunden abbildet. Diese erweitern wir nun um die Schnittstelle IDataErrorInfo. Da diese in der Bibliothek System.ComponentModel beschrieben wird, f&uuml;gen wir zun&auml;chst einen Verweis auf diese Schnittstelle per using-Schl&uuml;sselwort hinzu:<\/p>\n<pre>using System.ComponentModel;<\/pre>\n<p>Danach legen wir in der Kopfzeile der Klasse fest, dass diese die Schnittstelle IDataErrorInfo implementieren soll. Die Zeile sieht dann so aus:<\/p>\n<pre>public partial class Kunde : IDataErrorInfo {\r\n...<\/pre>\n<p>Um die Member dieser Schnittstelle schnell zu implementieren, w&auml;hlen Sie den Kontextmen&uuml;-Eintrag Schnellaktionen und Refactorings von IDataErrorInfo aus. Im nun erscheinenden Popup w&auml;hlen Sie Schnittstelle implementieren aus und erstellen so die beiden Methoden dieser Schnittstelle. Diese sehen zun&auml;chst wie folgt aus:<\/p>\n<pre>public string Error {\r\n     get {\r\n         throw new NotImplementedException();\r\n     }\r\n}\r\npublic string this[string columnName] {\r\n     get {\r\n         throw new NotImplementedException();\r\n     }\r\n}<\/pre>\n<p>Hier f&uuml;gen wir nun f&uuml;r die Methode this eine erste Validierung ein. Diese soll sicherstellen, dass die Eingabe in das Feld Vorname nicht offen bleibt.<\/p>\n<p>Die Methode this nimmt mit dem Parameter columnName immer den Namen des Feldes entgegen, das untersucht werden soll &#8211; in diesem Fall Vorname. Im get-Teil der Methode deklarieren wir die Variable result als string und pr&uuml;fen in einer if-Bedingung, ob columnName den Wert Vorname enth&auml;lt. Falls ja, pr&uuml;fen wir, ob Vorname den Wert null enth&auml;lt oder leer ist (IsNullOrEmpty). Ist das der Fall, stellen wir den R&uuml;ckgabewert mit der Variablen errorMessage auf den Text Bitte geben Sie einen Vornamen ein. ein (siehe Listing 1).<\/p>\n<pre>public string this[string columnName] {\r\n     get {\r\n         string errorMessage = \"\";\r\n         switch (columnName) {\r\n             case \"Vorname\":\r\n                 {\r\n                     if (String.IsNullOrEmpty(Vorname)) {\r\n                         errorMessage = \"Bitte geben Sie einen Vornamen ein.\";\r\n                     }\r\n                     break;\r\n                 }\r\n         }\r\n         return errorMessage;\r\n     }\r\n}<\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 1: Implementierung der Schnittstelle IDataErrorInfo in der Klasse Kunde.cs<\/span><\/b><\/p>\n<h2>.xaml-Code erweitern<\/h2>\n<p>Wenn Sie das Projekt nun starten, einen neuen Kunden anlegen und einen Vornamen mit maximal drei Zeichen angeben, tut sich jedoch erst einmal nichts. Das ist auch kein Wunder, denn wir haben ja im .xaml-Code auch noch nicht angegeben, dass es eine Validierung gibt.<\/p>\n<p>Damit die Methode this der Klasse Kunde.cs &uuml;berhaupt aufgerufen wird, m&uuml;ssen wir der Bindung des Textfeldes Vorname das Attribut ValidatesOnDataErrors hinzuf&uuml;gen und daf&uuml;r den Wert true festlegen:<\/p>\n<pre>&lt;TextBox x:Name=\"txtVorname\" Grid.Column=\"1\" Grid.Row=\"3\" HorizontalAlignment=\"Stretch\" Text=\"{Binding kunde.Vorname, Mode=TwoWay, ValidatesOnDataErrors=True}\" \/&gt;<\/pre>\n<p>Ein erneuter Start der Anwendung und die Eingabe eines ung&uuml;ltigen Ausdrucks zeigt nun Wirkung: Das fehlerhafte Feld wird mit einem roten Rahmen versehen (siehe Bild 2).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2016_06\/pic_67_006.png\" alt=\"Eine fehlerhafte Eingabe wird durch einen roten Rahmen markiert.\" width=\"499,6607\" height=\"306,1812\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: Eine fehlerhafte Eingabe wird durch einen roten Rahmen markiert.<\/span><\/b><\/p>\n<h2>Validierungshinweis anbringen<\/h2>\n<p>Nun fehlt noch der Hinweis f&uuml;r den Benutzer, damit er wei&szlig;, was er bei der Eingabe falsch gemacht hat. Dazu wollen wir rechts vom Textfeld ein Warnsymbol anzeigen, das beim &Uuml;berfahren mit der Maus einen ToolTip-Text einblendet. Dazu ist nicht mehr n&ouml;tig als die &Auml;nderung einiger Eigenschaften des TextBox-Elements. Da wir diese nicht nur f&uuml;r eine TextBox ben&ouml;tigen, sondern f&uuml;r alle, definieren wir direkt ein entsprechendes Style-Element in den Ressourcen des &uuml;bergeordneten Elements, hier also f&uuml;r ein Page-Element.<\/p>\n<div class=\"rcp_restricted\"><p><span style=\"color: #ff0000;\">M&ouml;chten Sie weiterlesen? Dann l&ouml;sen Sie Ihr Ticket!<\/span><br \/>\n<span style=\"color: #ff0000;\">Hier geht es zur Bestellung des Jahresabonnements des Magazins <strong>Visual Basic Entwickler<\/strong>:<\/span><br \/>\n<span style=\"color: #ff0000;\"><a style=\"color: #ff0000;\" href=\"https:\/\/shop.minhorst.com\/magazine\/363\/visual-basic-entwickler-jahresabonnement?c=77\">Zur Bestellung ...<\/a><\/span><br \/>\n<span style=\"color: #ff0000;\">Danach greifen Sie sofort auf <strong>alle rund 200 Artikel<\/strong> unseres Angebots zu - auch auf diesen hier!<\/span><br \/>\n<span style=\"color: #000000;\">Oder haben Sie bereits Zugangsdaten? Dann loggen Sie sich gleich hier ein:<\/span><\/p>\n<\/div>\n\n\t\n\t<form id=\"rcp_login_form\"  class=\"rcp_form\" method=\"POST\" action=\"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000067\/\">\n\n\t\t\n\t\t<fieldset class=\"rcp_login_data\">\n\t\t\t<p>\n\t\t\t\t<label for=\"rcp_user_login\">Username or Email<\/label>\n\t\t\t\t<input name=\"rcp_user_login\" id=\"rcp_user_login\" class=\"required\" type=\"text\"\/>\n\t\t\t<\/p>\n\t\t\t<p>\n\t\t\t\t<label for=\"rcp_user_pass\">Password<\/label>\n\t\t\t\t<input name=\"rcp_user_pass\" id=\"rcp_user_pass\" class=\"required\" type=\"password\"\/>\n\t\t\t<\/p>\n\t\t\t\t\t\t<p>\n\t\t\t\t<input type=\"checkbox\" name=\"rcp_user_remember\" id=\"rcp_user_remember\" value=\"1\"\/>\n\t\t\t\t<label for=\"rcp_user_remember\">Remember me<\/label>\n\t\t\t<\/p>\n\t\t\t<p class=\"rcp_lost_password\"><a href=\"\/data\/wp\/v2\/posts\/55000067?rcp_action=lostpassword\"><\/a><\/p>\n\t\t\t<p>\n\t\t\t\t<input type=\"hidden\" name=\"rcp_action\" value=\"login\"\/>\n\t\t\t\t<input type=\"hidden\" name=\"rcp_redirect\" value=\"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000067\/\"\/>\n\t\t\t\t<input type=\"hidden\" name=\"rcp_login_nonce\" value=\"22c77db969\"\/>\n\t\t\t\t<input id=\"rcp_login_submit\" class=\"rcp-button\" type=\"submit\" value=\"Login\"\/>\n\t\t\t<\/p>\n\t\t\t\t\t<\/fieldset>\n\n\t\t\n\t<\/form>\n<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Die Validierung bei der Eingabe von Daten ist eines der wichtigsten Themen bei der Erstellung benutzerfreundlicher Anwendungen. Nachdem der Artikel &#8220;EDM: Ausnahmen beim Speichern behandeln&#8221; gezeigt hat, wozu Sie im Rahmen der Validierung die durch Restriktionen im Datenmodell auftretenden Exceptions nutzen k&ouml;nnen, schauen wir uns nun einen einfachen Weg an, um Validierungsregeln in Entit&auml;tsklassen zu definieren und beim Fehlschlagen der Validierung entsprechende Meldungen in der Benutzeroberfl&auml;che auszugeben. Dabei zeigen wir hier den Umgang mit der Schnittstelle &#8220;IDataErrorInfo&#8221;.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[662016,66062016,44000008,44000021,44000027],"tags":[],"yst_prominent_words":[],"class_list":["post-55000067","post","type-post","status-publish","format-standard","hentry","category-662016","category-66062016","category-Datenzugriffstechnik","category-Entity_Framework","category-Excel_programmieren"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000067","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/comments?post=55000067"}],"version-history":[{"count":0,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000067\/revisions"}],"wp:attachment":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/media?parent=55000067"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/categories?post=55000067"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/tags?post=55000067"},{"taxonomy":"yst_prominent_words","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/yst_prominent_words?post=55000067"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}