Ich habe eine gebundene DataGridView. Eine Spalte enthält die Berechnungsweise (Festpreis/%). Eine ander enthält einen Decimal-Wert.
Hat der Benutzer "Festpreis" gewählt, dann sollte hinter dem Decimal-Wert im DGV ein " €" angefügt werden. Bei "Prozent" natürlich nur " %"
In VB.NET 2010 wollte ich das wie folgt lösen:
Private Sub dgvProductCalculation_CellFormatting(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) Handles dgvProductCalculation.CellFormatting Select Case dgvProductCalculation.Columns(e.ColumnIndex).Name Case "CalculatedPriceDataGridViewTextBoxColumn" If e.Value.ToString = System.Guid.Empty.ToString Or e.Value Is Nothing Or e.Value = CType("1.1.1900", Date) Then e.Value = "" Else Select Case dgvProductCalculation("dgvProductCalculationDiscountTypeGUID", e.RowIndex).Value.ToString Case "F5DCBC22-31C4-4a33-94D8-6424B61F0291" ' Festpreis e.Value = e.Value & " €" Case "9CF2F009-4560-4caf-AB3A-DC4B1015009F" ' Prozent e.Value = e.Value & " %" Case Else
End Select End If End Select End Sub
Leider kommt dabei aber der Fehler:
Der Operator = ist für Typ Decimal und Typ Date nicht definiert.
Kann ich den Wert an dieser Stelle nicht formatieren/anpassen?
Ich habe ein kleines Testprojekt aufgesetzt, in dem ich dein Problem nachgestellt habe. Wie Matthias und ich schon gesagt haben führt die Prüfung in Zeile 4 schon zu einem Fehler. Der Code führt dort zu einer InvalidCastException, wenn e.Value nicht vom Typ Date. Wenn e.Value Nothing ist, bekomme ich eine NullReferenceException. In keinem Fall komme ich bis in das Select Case. (Hier muss ich die Frage von Matthias wiederholen: Warum führst du eine Prüfung auf Date durch, wenn du einen Decimal in der Zelle erwartest?)
Dass bei dir im If keine Exception geworfen wird, muss übrigens nicht heißen. VB reicht nicht alle Exceptions weiter. Teilweise werden die Exception gefangen und lediglich eine Meldung im Output-Tab von Visual Studio ausgegeben. Ich habe zwar bis heute noch keine wirkliche Systematik hierzu herausgefunden, aber es scheint, dass dies für Exceptions, die in User-Controls oder im .NET-Framework auftreten, gilt.
Ich würde dir empfehlen "Option Strict On" zu setzen. Damit zwingst du VB, eine strengere Typprüfung bei Zuweisungen vorzunehmen. In deinem Codefragment würdest du 3 Fehler sehen. Der erste würde sich auf deine Datumsprüfung in der If-Anweisung beziehen (Option Strict On disallows operands of type Object for operator '='. Use the 'Is' operator to test for object identity.) Die beiden weiteren auf die beiden Zuweisungen mit "€" bzw. "%" (Option Strict On prohibits operands of type Object for operator '&').
Ich weiss warum ich eigentlich lieber in C# als in VB programmiere. Die automatischen Konvertierungen, die VB im Hintergrund durchführt, können zu inkonsistenten Zuständen führen, die dann nur sehr schwer zu debuggen sind. Deshalb achte ich auch in VB immer darauf, dass ich mit den korrekten Typen arbeite und führe, wenn notwendig, Typkonvertierungen explizit durch und verlasse mich nicht datauf, dass VB es schon richten wird.
Wenn Du Dir, wie in Deinem Kommentar zu luedis Antwort, wirklich ganz sicher bist, dass der Fehler in einer der beiden Zuweisungszeilen steckt, so gib bitte genau an, woher Du diese Sicherheit nimmst. Ich glaub's nämlich nicht.
Die einzige Stelle in Deinem Code, die meiner Meinung nach den Fehler hervorrufen kann, ist
... e.Value = CType("1.1.1900", Date) ...
in der 4. Zeile. Aus Deinen Erläuterungen geht hervor, dass e.Value initial mit einem Decimal gefüllt sein müßte, und den vergleichst Du hier mit einem Date (wozu eigentlich???). Das kann nicht gut gehen.
Übrigens: ließ Dir mal die Erläuterungen zum CellFormatting-Event durch. Was Du erreichen willst, ließe sich möglicherweise einfacher über die Format-Property und einen passenden CellStyle regeln. Und Du solltest wohl auch noch auf die FormattedValueType- und FormattingApplied-Eigenschaften achten.
Die Sicherheit nehm ich aus folgenden Beobachtungen:
1. Wenn ich dass SelectCase nach dem Else (das untere also) auskommentiere, dann läuft die Sache durch.
2. Wenn ich einen Breakpoint auf das selbe Select-Case setze dann hält er dort an - wertet meienen Wert aus - springt in das richtige CASE und bringt dann bei der Zuweisung des Textes den Fehler
Die beiden Links von dir, werd ich mir sofort mal durch lesen - danke
Strange... Die von mir angeführte Stelle müßte (wenn ich nicht grad auf der Leitung stehe) immer zu dem Fehler führen, denn wie luedi schrieb, hat der OR-Operator in VB.NET kein "short circuit"-Verhalten, der Vergleich wird also immer ausgeführt. Und die Fehlermeldung bezieht sich m.E. auf "=" als Vergleichs-, nicht als Zuweisungsoperator, und in den anderen Zeilen findet nun mal kein Vergleich statt. Irgendwas ist da faul. Schau Dir mal im Debugger den Stack-Trace an. Siehst Du da noch irgendwelche .NET-internen Aufrufe? Evtl. ist der Setter von e.Value ja etwas komplizierter...
Ich denke, das Problem ist, dass e.Value einen Decimal-Wert enthält und dieser natürlich nicht mit einem Date verglichen werden kann. Da VB bei "Or" immer alle Bedingungen prüft, wird der Fehler ausgegeben. Besser wäre es zu prüfen, ob die Zelle einen Decimal-Wert enthält:
Module Module1
Sub Main()
Dim result As Boolean
result = IsDecimal(New Decimal(42.0)) result = IsDecimal("Not a decimal")
End Sub
Function IsDecimal(ByRef pValue As Object) As Boolean
If TypeOf pValue Is Decimal Then Console.WriteLine("I'm a decimal") Return True End If
Console.WriteLine("I'm not a decimal") Return False
1. Wenn ich dass SelectCase nach dem Else (das untere also) auskommentiere, dann läuft die Sache durch.
2. Wenn ich einen Breakpoint auf das selbe Select-Case setze dann hält er dort an - wertet meienen Wert aus - springt in das richtige CASE und bringt dann bei der Zuweisung des Textes den Fehler
Die beiden Links von dir, werd ich mir sofort mal durch lesen - danke