Kann kein leeres Textfeld verlassen

8

Ich versuche, die Ursache eines nervigen Schnittstellenfehlers in einer App zu finden, die kürzlich von VS2003 auf VS2008 aktualisiert wurde (der Fehler war vor der Migration nicht vorhanden). Was passiert ist das:

1) Der Benutzer klickt in ein Textfeld mit einem Datum.
2) Benutzer löscht Datum
3) Der Benutzer versucht, in ein anderes Feld zu wechseln, kann dies aber nicht. Es werden keine Fehlermeldungen angezeigt - als ob die Validierung fehlgeschlagen wäre.

Weitere Informationen:

1) Die Text-Eigenschaft des Textfelds ist an eine Datenansicht gebunden, die eine Datentabelle als Quelle verwendet. Das gebundene Feld ist ein Nullable-Datetime-Feld ohne Einschränkungen oder Standard.
2) Das Validating-Ereignis wird ausgelöst und die CancelEventArgs-Eigenschaft wird nicht auf Abbrechen gesetzt. Die Ereignisse "Validated", "LostFocus" und "Leave" werden ebenfalls ausgelöst, wobei LostFocus & gt; Verlassen & gt; Validieren von 3) Ich kann keine Codeänderungen in Bezug auf das Steuerelement oder die Datenquelle mit ein paar Ausnahmen sehen. Das erste ist das:

%Vor%

hat sich nun folgendermaßen geändert:

%Vor%

Das zweite ist das:

%Vor%

hat sich nun folgendermaßen geändert:

%Vor%

Es gibt auch dieses, das seit dem ersten Tag im Code enthalten war:

%Vor%

Wenn ich jetzt das ", True" vom Hinzufügen der Datenbindung entferne, kann ich das Steuerelement mit einem leeren Wert verlassen, aber es wird dann auf den ursprünglichen Wert zurückgesetzt. Das Entfernen der Datumsformatierung scheint keinen Unterschied zu machen (es wird nur angezeigt, dass der 01.06.2011 00:00:00 statt der gewünschte 06/01/2010 angezeigt wird). Kein anderer Code verweist auf diese Textbox. Ich denke, dass sich etwas bei der Validierung von datengebundenen Steuerelementen zwischen VS2003 und VS2008 geändert haben muss, aber es ist genauso wahrscheinlich, dass ich etwas abstoss, das wirklich offensichtlich ist.

Irgendwelche Ideen?

    
MartW 06.01.2011, 13:24
quelle

2 Antworten

7

Der Grund dafür, dass Sie das beobachtete Verhalten sehen, liegt darin, dass Windows Forms und seine Datenbindung NULL-Datenbankwerte verarbeiten.

Der TL; DR Grund:

Siehe diesen Microsoft Connect-Vorschlag: Bessere Datenbindung Unterstützung für Nullable-Typen

Die lange Version:

Im Wesentlichen passiert Folgendes: Wenn Sie das Textfeld (in eine leere Zeichenfolge) leeren und anschließend wegklicken, konvertiert die Bindung die leere Zeichenfolge in DBNull Wert, der dann an die Datenquelle weitergegeben wird, jedoch versucht die Bindung, da es zweiseitig ist, das gebundene Steuerelement (die Textbox) erneut zu füllen mit entsprechender Formatierung und schlägt fehl, was dazu führt, dass die Textbox das merkwürdige Verhalten anzeigt, dass der Fokus nicht entfernt werden darf!

Dies geschieht aufgrund der Eigenschaft DataSourceNullValue von die Binding-Klasse . Dies kann mithilfe einer der Überladungen des Konstruktors des Binding-Klassensatzes erfolgen oder separat über eine Eigenschaftseinstellung festgelegt werden. Wenn Sie diese Eigenschaft jedoch nicht explizit festlegen, müssen Sie Folgendes beachten:

  

Der Standardwert ist DBNull für Werttypen   und null für Nichtwerttypen.

Es scheint, dass Sie nicht explizit diese Einstellung, so dass der Standard bewirbt, und mit Datetime-a Werttyp , verwendet DBNull.

Sobald die Datenquelle aktualisiert wurde (auf DBNull), versucht der Bindungsmechanismus, die Textbox mit dem neu aktualisierten Datenquellenwert erneut zu füllen. Wenn der zugrunde liegende Datenquellwert DBNull ist, wird der für das gebundene Steuerelement verwendete Wert von der Binding-Klasse NullValue-Eigenschaft . Wenn diese Eigenschaft nicht explizit entweder über das relevante überladene Konstruktorargument oder über die Eigenschaftseinstellung selbst festgelegt wird, wird der Standardwert verwendet:

  

Das Objekt, das als Steuerelement festgelegt werden soll   Eigenschaft, wenn die Datenquelle enthält   ein DBNull-Wert. Der Standardwert ist null.

Natürlich ist ein Textbox Eigenschaft Text können nur auf ein Objekt vom Typ System.String und keinen Nullwert (Nothing in VB), so dass die TextBox den repräsentativen Wert (null / nichts) des Wertes der Datenquelle (DBNull) nicht an das gebundene Steuerelement binden kann.

Die Möglichkeit, dieses Verhalten zu korrigieren ist, um sicherzustellen, dass die Die NullValue-Eigenschaft wird explizit auf einen geeigneten Wert gesetzt. In diesem Fall reicht eine Zeichenfolge mit der Länge Null aus, um das Problem zu beheben.

Eine Möglichkeit, dies zu erreichen, besteht darin, die Zeile zu ändern:

%Vor%

zu:

%Vor%

Der Schlüssel hier ist der allerletzte Parameter, der der NullValue ist, der auf eine Zeichenfolge mit der Länge null eingestellt ist (The DataSourceUpdateMode wird auch explizit angegeben aufgrund der Argumente des Konstruktors, aber es ist festgelegt wird, um es Standardwert ist jedenfalls).

Trotz allem scheint es etwas "merkwürdiges" Verhalten zu sein, wenn nicht sogar ein tatsächlicher Fehler. Dies wird auch durch andere belegt, die das gleiche Problem zu haben scheinen (was in Visual Studio 2010 / .NET 4.0 immer noch vorherrscht!). Dieser Thread auf der social.msdn .microsoft.com Foren enthält jemanden, der das gleiche Problem mit einigen interessanten möglichen Erklärungen erfährt, warum dies geschieht, und warum Microsoft es so entworfen hat.

Es gibt auch einen Microsoft Connect-Vorschlag das wurde bereits im Jahr 2005 berichtet, das das Problem hervorhebt. Dieser Vorschlag wurde "als verschoben abgelehnt". Es scheint, dass Microsoft es nicht als einen Fehler betrachtet, da eine sehr vernünftige Problemumgehung existiert (die explizite Einstellung der NullValue-Eigenschaft der Bindung), die aus Gründen der besseren Lesbarkeit sowieso getan werden sollte. Sie werden den Vorschlag in Zukunft offensichtlich berücksichtigen.

Zurück zu dem, warum das nicht existierte. Pre.NET 2.0 (Visual Studio 2005) scheint darauf zurückzuführen zu sein, dass der gesamte Datenbindungsmechanismus für die Veröffentlichung von .NET Framework 2.0 vollständig überarbeitet wurde. Ihre ursprüngliche Lösung, bei der es sich um ein VS2003-Projekt handelte, verwendete .NET Framework 1.1, das nicht über ein so umfangreiches Datenbindungs-Feature-Set verfügte. Obwohl ich keine Kopie von VS2003 mehr zur Hand habe, um das zu testen, gehe ich davon aus, dass der Bindungsmechanismus in .NET 1.1 viel mehr implizite Konvertierungen zwischen dem Wert des Steuerelements und dem Wert der Datenquelle verwendet. Dieses wird angezeigt, um unterstützt zu werden, wenn Sie die Binding-Klasse von . NET 1.1 , verglichen mit .NET 2.0 (oder höher). Zum Beispiel gab es keine Möglichkeit, (einfach) die tatsächliche bidirektionale Bindung selbst (und wie Werte zwischen dem Formular und der Datenquelle konvertiert werden) oder die Formatierung dieser Werte zu steuern.

    
CraigTP 07.02.2011, 12:09
quelle
0

Ich hatte diese Art von Fehler zuvor und musste sicherstellen, dass die zugrunde liegende Datenquelle (in meinem Fall war es ein Dataset) nicht auf schreibgeschützt eingestellt war und dass die Spalte "null" -Werte zuließ.

Sobald ich das getan hatte, hat alles gut funktioniert. Es schien, als ob der Fehler, der in den Datenbindungen geworfen wurde, irgendwo verschluckt wurde und sich nicht ausbreitete.

    
codingbadger 07.02.2011 09:17
quelle