DGV Sort Problem mit Selektion

  • VB.NET

Es gibt 26 Antworten in diesem Thema. Der letzte Beitrag () ist von Peter329.

    So ... jetzt hab ich die Routine auf Herz und NIeren getestet.

    Im großen und ganzen funktiioniert das mit dem Flag ... allerdings gibt es einen kleinen Bug:

    Wenn man die Selektion löscht und dann etwa die zweite Zeile selektiert, dann laufen folgende Events ab:

    Quellcode

    1. CellClick: i=-1
    2. CellClick: Set SelectionIsAllowed=True
    3. MouseClick: i=-1
    4. RowStateChanged: i=1
    5. RowStateChanged: SelectionIsAllowed=True
    6. SelectionChanged: i=1
    7. CellClick: i=1
    8. CellClick: Set SelectionIsAllowed=True
    9. MouseClick: i=1


    Das ist soweit auch alles in Ordnung. Die zweite Zeile wird selektiert (i=1).

    Wenn man aber die Selektion löscht, dann ein anderes Control anspricht (dadurch verliert die DGV den FOCUS) und nun die zweite Zeile anklick, dann sieht die Kette der Ereignisse anders aus:

    Quellcode

    1. CellEnter: i=-1
    2. CellEnter: SelectedRows.Count = 0
    3. CellEnter: Set SelectionIsAllowed=False
    4. RowStateChanged: i=1
    5. RowStateChanged: SelectionIsAllowed=False
    6. RowStateChanged: ClearSelection()
    7. RowStateChanged: i=-1
    8. RowStateChanged: SelectionIsAllowed=False
    9. RowStateChanged: ClearSelection()
    10. CellEnter: i=-1
    11. CellEnter: SelectedRows.Count = 0
    12. CellEnter: Set SelectionIsAllowed=False
    13. SelectionChanged: i=-1


    Durch das CellEnter wird SelectionIsAllowed=False gesetzt und damit wird die Selektion der zweiten Zeile wieder aufgehoben (i=-1) !

    Erst wenn man jetzt noch einmal die Zeile anklickt, wird die Selektion wirksam (i=1).

    Das ist natürlich ein sehr lästiges Verhalten. Leider ist mir keine richtige Lösung dazu eingefallen ... any bright ideas ?

    LG
    Peter
    @Peter329 Hast Du Deinen "finalen" Code schon gepostet?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ich habe an dem Coding von VaporiZed nichts geändert ! Ich habe nur Debug.Print Anweisungen eingefügt, um den Ablauf verfolgen zu können.

    Spoiler anzeigen
    Private SelectionIsAllowed As Boolean = True
    Private Trace As Boolean = False

    Private Sub FrmMain_Shown(sender As Object, e As EventArgs) Handles Me.Shown
    Trace = True
    Debug.Print("Load ended")
    Debug.Print("")
    End Sub
    Private Sub DataGridView1_MouseClick(sender As Object, e As MouseEventArgs) Handles DataGridView1.MouseClick
    Dim i As Integer = -1
    If DataGridView1.SelectedRows.Count > 0 Then i = DataGridView1.SelectedRows(0).Index
    Debug.Print("MouseClick: i=" & i.ToString)
    If e.Button = MouseButtons.Right Then
    Debug.Print("MouseClick: Button=Right - ClearSelection()")
    DataGridView1.ClearSelection()
    End If
    End Sub
    Private Sub DataGridView1_CellEnter(sender As Object, e As EventArgs) Handles DataGridView1.CellEnter
    Dim i As Integer = -1
    If DataGridView1.SelectedRows.Count > 0 Then i = DataGridView1.SelectedRows(0).Index
    Debug.Print("CellEnter: i=" & i.ToString)
    Debug.Print("CellEnter: SelectedRows.Count = 0")
    If Trace AndAlso DataGridView1.SelectedRows.Count = 0 Then
    SelectionIsAllowed = False
    Debug.Print("CellEnter: Set SelectionIsAllowed=" & SelectionIsAllowed.ToString)
    End If
    End Sub
    Private Sub DataGridView1_RowStateChanged(sender As Object, e As EventArgs) Handles DataGridView1.RowStateChanged
    Dim i As Integer = -1
    If DataGridView1.SelectedRows.Count > 0 Then i = DataGridView1.SelectedRows(0).Index
    Debug.Print("RowStateChanged: i=" & i.ToString)
    Debug.Print("RowStateChanged: SelectionIsAllowed=" & SelectionIsAllowed.ToString)
    If Not SelectionIsAllowed Then
    Debug.Print("RowStateChanged: ClearSelection()")
    DataGridView1.ClearSelection()
    DataGridView1.CurrentCell = Nothing
    End If
    End Sub
    Private Sub DataGridView1_CellClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellClick
    Dim i As Integer = -1
    If DataGridView1.SelectedRows.Count > 0 Then i = DataGridView1.SelectedRows(0).Index
    Debug.Print("CellClick: i=" & i.ToString)
    SelectionIsAllowed = True
    Debug.Print("CellClick: Set SelectionIsAllowed=" & SelectionIsAllowed.ToString)
    End Sub
    Private Sub DataGridView1_SelectionChanged(sender As Object, e As EventArgs) Handles DataGridView1.SelectionChanged
    Dim i As Integer = -1
    If DataGridView1.SelectedRows.Count > 0 Then i = DataGridView1.SelectedRows(0).Index
    Debug.Print("SelectionChanged: i=" & i.ToString)
    End Sub


    Übrigens: auch nach einem Sort ohne selektierte Row, trtt der gleiche Effekt auf: um eine Zeile jetzt zu selektieren, muss man sie zweimal anklicken !

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

    @Peter329 Ich kann das hier nicht nachvollziehen, ich muss das mal zu Hause testen.
    Was hast Du für ein Studio und welches Framework verwendest Du?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ok ... ich habe jetzt eine Lösung gefunden !

    Ich stelle den Sort Mode auf PROGRAMMATIC und behandle den Click auf den Column Header einfach selbst ! :)

    Das sind ein paar Zeilen Code und die Sache ist erledigt. Ich bin dabei das hübsch zu kodieren und stelle die fertige Lösung dann hier ein.

    LG
    Peter
    Tja ... das klang zwar gut ... aber leider kommt man auch damit nicht weiter !

    Auch mit SortMode=Programmatic ist das Verhalten das Gleiche: wenn keine Zeile selektiert ist, dann wird durch den Click auf den Column Header eine Zeile automatisch selektiert. Und das geschieht lange bevor das Ereignis ColumnHeaderClick feuert. Und deshalb kann ich das nicht so einfach abfangen !

    Ich habe einfach keine Technik gefunden, SICHER zu entscheiden, ob eine Zeile explizit selektiert wurde (etwa durch einen Click auf die Zeile) oder ob sie implizit durch den Klick auf den Column Header zugeordnet wurde.

    Das .Net Framework will halt im Sort nicht zulassen, dass in der DatagridView KEINE Zeile ausgewählt ist. Und nach all den Versuchen scheint es mir, dass man sich mit dem Räderwerk des .Net besser nicht anlegt ! :)

    Ich lebe jetzt halt damit, dass beim Sort ohne Select eine Zeile implizit selektiert wird ... und klicke halt die rechte Maustaste, um das wieder zu löschen. Es gibt schlimmeres im Leben ... aber wenigstens hab ich es versucht ! :)

    LG
    Peter