Dataset Expression berechnet nicht nach ändern des Wertes einer Zelle

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von KingLM97.

    Dataset Expression berechnet nicht nach ändern des Wertes einer Zelle

    Hallo,

    ich habe hier folgende Tabelle im typisiertem Dataset (s. Anhang).

    Die Tabelle ist an ein DGV gebunden. Der User kann über die Oberfläche verschiedene Bestellungen hinzufügen. Alle Werte sind ReadOnly im DGV, außer Anzahl. Dafür habe ich mir aus dem Netz eine NumericUpDownColumn gezogen. Ändert der User also die Anzahl, soll in der Spalte GPreis der komplette Preis stehen (also Preis * Anzahl). Das funktioniert aber nicht. Ändern tut sich rein garnichts. Erhöhe ich per Code die Anzahl um +1, wenn der User das selbe nochmal bestellt, dann funktioniert alles tadellos. Das möchte ich so aber nicht.

    Vllt hilft der Code des NumericUpDown.

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class NumericUpDownColumn
    2. Inherits DataGridViewColumn
    3. Public Sub New()
    4. MyBase.New(New NumericUpDownCell())
    5. End Sub
    6. Public Overrides Property CellTemplate() As DataGridViewCell
    7. Get
    8. Return MyBase.CellTemplate
    9. End Get
    10. Set(ByVal value As DataGridViewCell)
    11. ' Ensure that the cell used for the template is a CalendarCell.
    12. If Not (value Is Nothing) AndAlso Not value.GetType().IsAssignableFrom(GetType(NumericUpDownCell)) Then
    13. Throw New InvalidCastException("Must be a CalendarCell")
    14. End If
    15. MyBase.CellTemplate = value
    16. End Set
    17. End Property
    18. End Class
    19. Public Class NumericUpDownCell
    20. Inherits DataGridViewTextBoxCell
    21. Public Sub New()
    22. ' Use the short date format.
    23. Me.Style.Format = "#.##"
    24. End Sub
    25. Public Overrides Sub InitializeEditingControl(ByVal rowIndex As Integer, ByVal initialFormattedValue As Object, ByVal dataGridViewCellStyle As DataGridViewCellStyle)
    26. ' Set the value of the editing control to the current cell value.
    27. MyBase.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle)
    28. Dim ctl As NumericUpDownEditingControl = CType(DataGridView.EditingControl, NumericUpDownEditingControl)
    29. If Me.Value.Equals(DBNull.Value) Then
    30. ctl.Value = 0
    31. Else
    32. ctl.Value = CType(Me.Value, Decimal)
    33. End If
    34. End Sub
    35. Public Overrides ReadOnly Property EditType() As Type
    36. Get
    37. ' Return the type of the editing contol that CalendarCell uses.
    38. Return GetType(NumericUpDownEditingControl)
    39. End Get
    40. End Property
    41. Public Overrides ReadOnly Property ValueType() As Type
    42. Get
    43. ' Return the type of the value that CalendarCell contains.
    44. Return GetType(Decimal)
    45. End Get
    46. End Property
    47. Public Overrides ReadOnly Property DefaultNewRowValue() As Object
    48. Get
    49. ' Use the current date and time as the default value.
    50. Return 0
    51. End Get
    52. End Property
    53. End Class
    54. Class NumericUpDownEditingControl
    55. Inherits NumericUpDown
    56. Implements IDataGridViewEditingControl
    57. Private dataGridViewControl As DataGridView
    58. Private valueIsChanged As Boolean = False
    59. Private rowIndexNum As Integer
    60. Public Sub New()
    61. Me.DecimalPlaces = 2
    62. End Sub
    63. Public Property EditingControlFormattedValue() As Object Implements IDataGridViewEditingControl.EditingControlFormattedValue
    64. Get
    65. Return Me.Value.ToString("#.##")
    66. End Get
    67. Set(ByVal value As Object)
    68. If TypeOf value Is Decimal Then
    69. Me.Value = Decimal.Parse(value.ToString)
    70. End If
    71. End Set
    72. End Property
    73. Public Function GetEditingControlFormattedValue(ByVal context As DataGridViewDataErrorContexts) As Object Implements IDataGridViewEditingControl.GetEditingControlFormattedValue
    74. Return Me.Value.ToString("#.##")
    75. End Function
    76. Public Sub ApplyCellStyleToEditingControl(ByVal dataGridViewCellStyle As DataGridViewCellStyle) Implements IDataGridViewEditingControl.ApplyCellStyleToEditingControl
    77. Me.Font = dataGridViewCellStyle.Font
    78. Me.ForeColor = dataGridViewCellStyle.ForeColor
    79. Me.BackColor = dataGridViewCellStyle.BackColor
    80. End Sub
    81. Public Property EditingControlRowIndex() As Integer Implements IDataGridViewEditingControl.EditingControlRowIndex
    82. Get
    83. Return rowIndexNum
    84. End Get
    85. Set(ByVal value As Integer)
    86. rowIndexNum = value
    87. End Set
    88. End Property
    89. Public Function EditingControlWantsInputKey(ByVal key As Keys, ByVal dataGridViewWantsInputKey As Boolean) As Boolean Implements IDataGridViewEditingControl.EditingControlWantsInputKey
    90. ' Let the DateTimePicker handle the keys listed.
    91. Select Case key And Keys.KeyCode
    92. Case Keys.Left, Keys.Up, Keys.Down, Keys.Right, Keys.Home, Keys.End, Keys.PageDown, Keys.PageUp
    93. Return True
    94. Case Else
    95. Return False
    96. End Select
    97. End Function
    98. Public Sub PrepareEditingControlForEdit(ByVal selectAll As Boolean) Implements IDataGridViewEditingControl.PrepareEditingControlForEdit
    99. ' No preparation needs to be done.
    100. End Sub
    101. Public ReadOnly Property RepositionEditingControlOnValueChange() As Boolean Implements IDataGridViewEditingControl.RepositionEditingControlOnValueChange
    102. Get
    103. Return False
    104. End Get
    105. End Property
    106. Public Property EditingControlDataGridView() As DataGridView Implements IDataGridViewEditingControl.EditingControlDataGridView
    107. Get
    108. Return dataGridViewControl
    109. End Get
    110. Set(ByVal value As DataGridView)
    111. dataGridViewControl = value
    112. End Set
    113. End Property
    114. Public Property EditingControlValueChanged() As Boolean Implements IDataGridViewEditingControl.EditingControlValueChanged
    115. Get
    116. Return valueIsChanged
    117. End Get
    118. Set(ByVal value As Boolean)
    119. valueIsChanged = value
    120. End Set
    121. End Property
    122. Public ReadOnly Property EditingControlCursor() As Cursor Implements IDataGridViewEditingControl.EditingPanelCursor
    123. Get
    124. Return MyBase.Cursor
    125. End Get
    126. End Property
    127. Protected Overrides Sub OnValueChanged(ByVal eventargs As EventArgs)
    128. ' Notify the DataGridView that the contents of the cell have changed.
    129. valueIsChanged = True
    130. Me.EditingControlDataGridView.NotifyCurrentCellDirty(True)
    131. MyBase.OnValueChanged(eventargs)
    132. End Sub
    133. End Class


    Das ist mein erstes Projekt mit typisierten Datasets, entschuldigt also wenn ich einfach einen Denkfehler habe :)

    Ich bin für jede Hilfe Dankbar.

    Edit: Er scheint es zu berechnen, wenn eine neue Bestellung hinzugefügt wird. Bringt mir auch nicht viel, besonders dann, wenn der User keine weitere Bestellung vornimmt. Dann stimmt die Spalte dennoch nicht...

    *Topic verschoben*
    Bilder
    • Unbenannt.png

      14,74 kB, 540×338, 88 mal angesehen

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Marcus Gräfe“ ()

    Im Anhang ein Beispielprojekt.

    Füge ich etwas hinzu, ändere in der Spalte Anzahl die Anzahl ändert sich GPreis nicht. Erst, wenn eine neue Row hinzukommt.
    Dateien
    • Blah.zip

      (38,83 kB, 97 mal heruntergeladen, zuletzt: )
    @VB1963: Du musst im Projektexplorer über [alle Dateien anzeigen] bei "My Resources" die licenses.resx löschen, dann geht's.

    Ich kann das Problem nicht nachvollziehen. Ich mache folgendes:
    Programm starten
    Feld 1: 5 eintragen
    Feld 2: 10 eintragen
    [+] anklicken
    in DGV-Zeile 1, Spalte Anzahl reingehen => NUD-CE erscheint
    Wert z.B. mit den Pfeilen ändern
    Enter drücken => Wert aus dem NUD wird akzeptiert und der Gesamtpreis richtig berechnet.

    Ah, jetzt erkenn ich das Problem. Man muss den Wert im NUD, wenn man es per Tastatur ändern will, 2x eintragen und mit Enter bestätigen, bevor es akzeptiert wird. Riecht für mich nach Fehler im NUD-ColumnControl.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Ja stimmt, da ist noch die Lizenzdatei dabei gewesen, die wird leider standardmäßig eingefügt.

    Ja gut, wenn ich es mit Enter bestätige, funktioniert es. Aber ich glaube nicht, dass das jeder User machen wird/will, wenn er bei mehreren Bestellungen die Anzahl ändern will.
    Wenn ich nicht recht entsinne triggert das CellValueChanged (oder wie das auch immer heißt, bin am Handy aktuell) beim ändern mittels des NUD nicht.

    Es funktioniert aber auch nicht, wenn ich nur mittels NUD die Anzahl ändere, ohne Enter. Da wäre eine quasi Liveanzeige was feines.
    jo, normal wird ein per Databinding eingegebner Wert übernommen, wenn der Datensatz gewechselt wird (etwa durch Drücken von Enter). Ist ja sinnvoll, weil meist sind ja mehrere Sachen in einem DS einzutragen.

    Aber wenn sofort bei jeder Änderung übernommen werden soll, dann kann man beim Binding unter Erweiterte Einstelungen DataSourceUpdateMode.OnPropertyChanged einstellen.
    Den Hinweis blick ich in diesem Zusammenhang nicht. Wie erstellt man denn für ne einzelne Spalte in nem DGV ein erweitertes Binding?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Sorry, aber auch wenn das nicht mein Thread ist, ich komm da nicht weiter.
    In welchem CE hast Du diese Auswahl des AdvancedBindings? In der NumericUpDown-DGV-Column selbst wird es mir nicht angeboten:

    Im DGV selbst kann man einiges per AdvancedBinding einstellen. Aber ergibt das einen Sinn? Man kann zwar DataSource und DataMember so festlegen. Aber DataSource ist schon mit der BindingSource gekoppelt und DataMember auf irgendwas aus folgendem Fenster festzulegen, führt doch zu nix, da entsteht ja Mus:


    Das sowas für ein NumericUpDown-CE selbst geht, ist klar. Aber es geht ja hier um diese DGV-Column.

    Von daher: Mit welchem CE entstand Dein Screenshot? Oder ging es bei dem nur darum darauf hinzuweisen, wo man AdvancedBinding grundsätzlich findet?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    ups - DGV!

    mal wieder schlampig gelesen.
    Die gezeigte Einstellung geht nur bei "normalen" Controls, Textbox, Datepicker etc. - aber nicht inne DGV-Column

    Jo, bei DGV muss man dem Databinding "nachtreten", etwa im CellEdited-Event oder so (weiß grad nicht wie das Event richtig heisst) ein BindingSource.EndEdit() aufruft.
    Habe das Problem jetzt anders gelöst -mehr oder weniger.

    Habe die Spalte "Anzahl" auf ReadOnly gesetzt, das NUD entfernt und stattdessen zwei ungebundene Spalten mit jeweils einem Button für "+" und "-" gemacht. Beim klick schaue ich einfach in der BindingSource auf die Current-Eigenschaft, Caste mir die Row daraus und setze Anzahl dementsprechend :)