checkstate im dgv ändern

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

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

    checkstate im dgv ändern

    Guten Abend,

    folgende Situation:

    Zugrunde liegt ein typisiertes dataset.
    Dort gibt es eine column welche Ich als checkbox darstelle.
    Wenn nun der Bediener im dgv auf diese checkbox klickt, möchte ich das abfangen und fragen, ob er
    diese wirklich auf false setzen möchte.

    Bis dahin kein Problem.....

    Aber wie bekomme ich es hin, dass der Haken nicht weggeht?

    Mein Ansatz:

    VB.NET-Quellcode

    1. ToDoDataGridView.CurrentRow.Cells(ToDoDataGridView.Columns("Erledigt").Index).Value = CheckState.Checked

    gehtr aber nicht.....

    Wie kann ich das realisieren?

    kiter20
    "Mann" lernt mit seinen Projekten.

    kiter20 schrieb:

    Zugrunde liegt ein typisiertes dataset.
    Welches auch für solche Aktionen verwendet werden sollte. Ein DGV ist zur Darstellung gedacht und weniger zur codetechnischen Manipulation der Daten. Schnapp Dir die typisierte, aktuelle DataRow und ändere dort den betreffenden Boolean-Wert. Wenn das DGV korrekt an das tDS gebunden ist, kümmert sich die BindingSource darum, dass alles so läuft, wie Du es brauchst.
    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.
    verstehe ich das richtig, dass du datenabhängig bestimmte Zellen der CheckboxDgvColumn Readonly haben möchtest?

    Wenn dem so ist, muss man imo doch am Dgv manipulieren - die Daten-Infrastruktur gibt das glaub nicht her.
    Ich würd ans .CellContentClkick denken, oder an _CellValidating - letzteres müsste sogar ein CancelEventArgs liefern (wenns _CellValidatiing ühaupt gibt - ich hab nicht nachgeguckt).
    Ich habe ein DataSet namens TdsTest, darin eine DataTable namens TdtTest, darin 2 Spalten: ID (unique autoincremental int) und isTrue (Boolean); im Form ein DGV und die automatisch erstelle BindingSource BsTest. Dazu der folgende Code:

    VB.NET-Quellcode

    1. Private Sub DgvTest_CellValidated(sender As Object, e As DataGridViewCellEventArgs) Handles DgvTest.CellValidated
    2. If e.ColumnIndex = 0 OrElse e.RowIndex = DgvTest.Rows.Count - 1 Then Exit Sub
    3. DirectCast(DirectCast(BsTest.Current, DataRowView).Row, TdsTest.TdtTestRow).IsTrue = CBool(DgvTest.CurrentCell.Value)
    4. MessageBox.Show(DirectCast(DirectCast(BsTest.Current, DataRowView).Row, TdsTest.TdtTestRow).IsTrue.ToString)
    5. End Sub

    läuft

    Wo ist der funktionale Unterschied, warum das nicht verwendet werden kann?
    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.
    Wenn das geht ist gut - habich mich geirrt.
    Tut es, was es soll? also sorgt es dafür, dass .IsTrue zwar auf True gestellt wern kann, dann aber nicht zurück?


    Ich hätte erwartet, dasses Probleme gibt, weil die dgv-Änderung noch gar nicht in der Datarow angekommen ist - IEditableObject.EndEdit hat noch nicht stattgefunden.
    Kannst du deine TestSolution vlt. zippen und anhängen? Zum selber eine basteln bin ich zu faul.


    Ach - sind ja noch ungelegte Eier- Kiter20 hat ja noch nicht bestätigt oder korrigiert, ob ich ihn ühaupt richtig verstund.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()

    check
    Warum auch immer das gute Stück 360 kB groß ist 8|

    EDIT:
    mit Sicherheitsfrage:

    VB.NET-Quellcode

    1. If e.ColumnIndex = 0 OrElse e.RowIndex = DgvTest.Rows.Count - 1 Then Exit Sub
    2. If MessageBox.Show("Wirklich ändern?", "Sicher?", MessageBoxButtons.OKCancel) = DialogResult.OK Then
    3. DirectCast(DirectCast(BsTest.Current, DataRowView).Row, TdsTest.TdtTestRow).IsTrue = CBool(DgvTest.CurrentCell.Value)
    4. End If

    Aber ich glaub, langsam dämmert's bei mir. Diese Sicherheitsfrage soll wohl dann auftauchen, wenn man das Feld anklickt und nicht erst, wenn man die Zelle bestätigt, indem man sie verlässt.

    EDIT: Dann sollte es mit folgendem klappen:

    VB.NET-Quellcode

    1. Private Sub DgvTest_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles DgvTest.CellContentClick
    2. If e.ColumnIndex = 0 OrElse e.RowIndex = DgvTest.Rows.Count - 1 Then Exit Sub
    3. Dim ActualValue = False
    4. If MessageBox.Show("Wirklich ändern?", "Sicher?", MessageBoxButtons.OKCancel) = DialogResult.OK Then
    5. ActualValue = Not CBool(DgvTest.CurrentCell.Value)
    6. Else
    7. ActualValue = CBool(DgvTest.CurrentCell.Value)
    8. End If
    9. DirectCast(DirectCast(BsTest.Current, DataRowView).Row, TdsTest.TdtTestRow).IsTrue = ActualValue
    10. End Sub

    Dateien
    • WindowsApp1.zip

      (358,28 kB, 77 mal heruntergeladen, zuletzt: )
    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.

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „VaporiZed“ ()

    Erst einmal Danke, dass ihr euch meiner annehmd.
    @ErfinderDesRades @VaporiZed

    Es handelt sich bei dieser Tabelle um eine ToDo Liste.
    Sobald der Benutzer auf das Kästchen erledigt klickt, wird in einer anderen Zelle, der aktuelle Zeitstempel gesetzt und das Häkchen bei erledigt gesetzt.

    Wenn man noch einmal auf erledigt klickt, wird der Zeitstempel auf min gesetzt.

    Mit einer Sciherhgeitsabfrage mochte ich nun verhindern, dass der Benutzer aus versehen den Zeitstempel zurück setzt.

    Mein Ansatz war es einfach den Wert wieder auf true zu setzen.
    Aber irgendwie geht das nicht.
    Der Wert der BS ist zwar true, aber das Häkchen geht weg.

    Mein neuer Ansatz war jetzt das CellBeginEdit abzufangen.
    Und mit CancelEdit abzubrechen.

    Prinzipiell scheint das der richtige Weg zu sein.
    Aber.....
    bei dem ersten klick auf die Zelle wird das Häkchen kurz gesetzt und geht sofort wieder weg. Das Datum wird korrekt gesetzt.
    Danach steht die row noch im Bearbeitungsmodus.
    Also muss man die Zeile einmal verlassen, bevor das event neu gefeuert wird.

    Was könnte das mit dem Häkchen sein und wie kann ich den Bearbeitung modus beenden?
    "Mann" lernt mit seinen Projekten.
    Mag jetzt vielleicht n bisken zugeknöpft klingen, aber hast Du Dir denn mal mein Projektvorschlag angeschaut? Sollte doch so ziemlich das bewerkstelligen, was Du brauchst, oder? Hier nochmal auf die spezifischeren Anforderungen zugeschnitten.

    btw: Was meinst Du mit »Wenn man noch einmal auf erledigt klickt, wird der Zeitstempel auf min gesetzt.« 01.01.0001? Falls ja, schau mal ggf. bei EDRs Nullable DateTimePicker

    Dateien
    • WindowsApp1.zip

      (116,33 kB, 80 mal heruntergeladen, zuletzt: )
    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.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VaporiZed“ ()

    VaporiZed schrieb:

    Mag jetzt vielleicht n bisken zugeknöpft klingen


    Kein Problem. Kann Ich mit umgehen. (Hast ja nicht ganz unrecht.)
    Schein aber mit deiner variante zu gehen.

    Sry, aber Ich lade nur ungern Daten irgendwo runter.(Ist nicht persönlich oder gegen irgend jemand anderes)

    Ich werde dann mal nen bissl feintuning machen und checken ob das so geht wie ich es mir vorgestellt habe.
    Ich werd mich auf jeden Fall nochmal dazu melden.
    Das mit dem Datum ist gut so wie es ist. So kann man sehen, dass der Wert schon mal gesetzt war.

    Besten Dank

    Kiter20
    "Mann" lernt mit seinen Projekten.
    Danke :thumbsup:

    VB.NET-Quellcode

    1. If ToDoDataGridView.Columns(e.ColumnIndex).Name = "Erledigt" Then
    2. Dim TaskIsActualDone = False
    3. If DirectCast(DirectCast(ToDoBindingSource.Current, DataRowView).Row, ToDoDataSet.ToDoRow).Erledigt = False Then
    4. If MessageBox.Show("Ist diese Aufgabe wirklich abgeschlossen?", "Sicher?", MessageBoxButtons.OKCancel) = DialogResult.OK Then
    5. TaskIsActualDone = True
    6. Else
    7. TaskIsActualDone = False
    8. End If
    9. Else
    10. If MessageBox.Show("Soll der Status zurück gesetzt werden?", "Sicher?", MessageBoxButtons.OKCancel) = DialogResult.OK Then
    11. TaskIsActualDone = False
    12. Else
    13. TaskIsActualDone = True
    14. End If
    15. End If
    16. DirectCast(DirectCast(ToDoBindingSource.Current, DataRowView).Row, ToDoDataSet.ToDoRow).Erledigt = TaskIsActualDone
    17. DirectCast(DirectCast(ToDoBindingSource.Current, DataRowView).Row, ToDoDataSet.ToDoRow).TimeReady = If(TaskIsActualDone, DateTime.Now.Date, DateTime.MinValue)
    18. End If
    "Mann" lernt mit seinen Projekten.
    Vereinfachung und Verbesserung der Leserlichkeit/Wartbarkeit:

    VB.NET-Quellcode

    1. If ToDoDataGridView.Columns(e.ColumnIndex).Name = "Erledigt" Then
    2. Dim rwToDo = DirectCast(DirectCast(ToDoBindingSource.Current, DataRowView).Row, ToDoDataSet.ToDoRow)
    3. Dim msg = If(rwToDo.Erledigt, "Soll der Status zurück gesetzt werden?", "Ist diese Aufgabe wirklich abgeschlossen?")
    4. If MessageBox.Show(msg, "Sicher?", MessageBoxButtons.OKCancel) = DialogResult.OK Then rwToDo.Erledigt = Not rwToDo.Erledigt
    5. rwToDo.TimeReady = If( rwToDo.Erledigt, DateTime.Now.Date, DateTime.MinValue)
    6. End If
    Oder so:

    VB.NET-Quellcode

    1. If ToDoDataGridView.Columns(e.ColumnIndex).Name <> "Erledigt" Then Return
    2. Dim rwToDo = DirectCast(DirectCast(ToDoBindingSource.Current, DataRowView).Row, ToDoDataSet.ToDoRow)
    3. Dim msg = If(rwToDo.Erledigt, "Soll der Status zurück gesetzt werden?", "Ist diese Aufgabe wirklich abgeschlossen?")
    4. If MessageBox.Show(msg, "Sicher?", MessageBoxButtons.OKCancel) <> DialogResult.OK Then Return
    5. rwToDo.Erledigt = Not rwToDo.Erledigt
    6. rwToDo.TimeReady = If(rwToDo.Erledigt, DateTime.Now.Date, DateTime.MinValue)

    Tatsächlich besteht ein Datenmodell-Fehler. Die Spalte Erledigt erübrigt sich, weil die Spalte TimeReady bereits eindeutig bestimmt, ob Erledigt ist oder nicht.
    Eine berechnete Spalte wäre in Betracht zu ziehen, oder auch eine ungebundene DgvCheckboxColumn

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()