none
DGV Sort Bug oder eigene Unfähigkeit

    Frage

  • Hallo,

    Ich hab nen DGV mit ca. 30 Spalten und je nach Datenquelle 1 - 950 Zeilen.

    Ich erhalte über eine Datenbankabfrage eine Datatable , packe das zwecks bestimmter Funktionen in ein DataView und binde das als Datasource an das DGV

    Die Spalten werden alle Sortmode = programatic gesetzt

    Grund : Durch berechnungen ändert sich da öfters viele Werte , DGV sortiert nach jeder Wertänderung neu
    (ob ein Datatable das macht , hab ich noch gar nicht drüber nachgedacht , neuer Ansatzpuntk)

    Aufjedenfall deaktiviere ich während den Berechnungen die Sortierungen des Datatables , Berechne sämtliche Spalten und lass neu sortieren.

    Spalte X ist vom Datentyp Float/ Double .

    Nach der Berechnung kommt folgende Anfangssortierung raus :

    n. def.

    n. def.

    5,40

    5,06

    5,08

    5,14

    ...

    wenn ich (hab ich ebend erst mitbekommen ) die entsprechenden Zellen jetzt versuche zu makieren , löst er nach 3 zellen wohl eine Sortierung aus und kriegt "den Fehler " mit.

    Wenn ich jetzt neu berechne , ist die Sortierung sofort richtig.

    Hab jetzt schon diverse Tipps / Tutorials / MSDN Anleitungen gelesen.

    Entweder ich hab das richtige nicht gefunden oder der Fehler is so Banal das nur ich mal wieder nicht drauf komme.

    Ich habs jetzt auch mit einem

    Me.SelectAll()
    Me.ClearSelection()

    da er auf die anderen Versuche wie , resize , mehrfaches sort aufrufen nicht reagiert.

    Private Sortierung As String = ""

     Public WriteOnly Property Sortable As Boolean
            Set(value As Boolean)
                Try
                    If value Then
                        Me.ClearSelection()

                        Me.DataSource.Sort = Sortierung

                        Me.SelectAll()
                        Me.ClearSelection()
                    Else
                        Sortierung = Me.DataSource.Sort
                        Me.DataSource.Sort = ""
                    End If
                Catch ex As Exception

                End Try
            End Set
        End Property

    Bei der Art und Weise des Quellcodes sag ich vorne weg :

    Das ist eine "Quick and Dirrty , ich bau alle Funktionen ein und dann erstell ich ein abgesichtertes , leistungsfähiges DGV draus" System.

    Donnerstag, 15. August 2013 09:08

Alle Antworten

  • Hi Florian,
    die Liste mit den Datenobjekten bleibt immer unsortiert, d.h. die Datenobjekte verbleiben immer in der Reihenfolge, wie die Liste gefüllt wurde.

    Sortiert (und gefiltert) wird in einer Sicht, die man sich wie einen übergestülpten Index vorstellen kann, über den die Anzeige die Datensätze abruft und der Index das entsprechende Datenobjekt zur Anzeige bereitstellt. Diese Sicht kann entweder explizit erstellt werden oder sie wird implizit erstellt, wenn man die Liste direkt als Datenquelle bindet.

    Aus Deinen Ausführungen entnehme ist, dass Du als Liste mit den Datenobjekten die Rows-Auflistung des DataTable Objektes nutzt und als Sicht explizit ein DataView-Objekt einsetzt.

    Um in diesem Prozess problemlos zu arbeiten, sollten alle Sortier- und Filtervorgänge direkt mit der Sicht ausgeführt werden. In deinem Codeausschnitt nutzt Du aber den Umweg über das Anzeigeelement (Grid). Das kann zu unschönen seiteneffekten führen.

    Arbeite mal direkt mit der Sicht.

    --
    Peter

    Donnerstag, 15. August 2013 11:45
  • Hallo Peter,

    DataTable -> DataView -> DataGridView Problem .

    Ich werds morgen mal testen!

    klingt auf jedenfall schlüssig.

    Das Ergebnis geb ich dann morgen bekannt !

    Vielen Dank

    Florian

    Donnerstag, 15. August 2013 13:31
  • So,

    Nach langem Suchen habe ich die Lösung endlich gefunden.

    Der Ansatz von Peter ist und war schon ganz richtig, es fehlte nur noch das i Tüpfelchen.

    Also ich Versuch mal den Lösungsansatz zu erklären :

    In einem C# Forum habe ich einen Beitrag gelesen , wo ein Problem mit dem EndEdit() des DataGridViews bestand.

    Ich habe das Eintragen der Berechnung vom DataGridView in das DataView verschoben.

    Hier gab es noch keine Veränderung , selbes Problem.

    Auch das Auslösen des der EndEdit Routine brachte keinen Erfolg. Ist ja auch logisch , da die Spalte nicht Editierbar ist laut DGV.

    Was nun aber beim Berechnen editiert wird , ist das Dataview , welches auch einen Edit Modus hat.

    dieses wird unter umständen nicht immer vom DataGridview bei programmseitiger Manipulation geschlossen.

    row.EndEdit() löst dieses Problem.

    Liege ich da mit meiner Annahme / behauptung richtig ?!

    Dienstag, 20. August 2013 13:03
  • Hi Florian,
    ausgehend von den von Dir genutzten Begriffen, nutzt Du ein DataGridView in einer klassischen Windows Forms Anwendung mit komplexer Bindung. Für die Steuerung der Bindung ist der BindingManager verantwortlich. Zum Ende des Editierungsvorganges teilt der BindingManager den Binding Objekten mit, dass das Editieren des aktuellen Datensatzes zu beenden ist, d.h., aus den Steuerelementen werden die geänderten Daten in die Datenquelle geschrieben. Das Ende des Editorganges kann explizit per Befehl oder auch implizit durch Datensatzwechsel ausgelöst werden. 

    Das DataView Objekt hat selbst mit dem Editvorgang nichts zu tun. Von verschiedenen Objekten kann das Ende des Editvorganges an den BindingManager gemeldet werden. Dazu werden auch EndEdit-Methoden genutzt. Am besten ist es, wenn man aber den BindingManager direkt nutzt und bei ihm die EndCurrentEdit-Methode aufruft. das klappt dann immer. Voraussetzung ist lediglich, dass man den richtigen BindingManager anspricht. Einige Steuerelemente wie Form oder Panel verwalten für jeden BindingContext einen BindingManager. Um also den richtigen BindingManager zu nutzen, muss man mit dem richtigen BindingContext den BindingManager vom entsprechenden Container holen. Da das nicht immer einfach ist, hat Microsoft die BindingSource-Klasse spendiert. Sie kapselt eine Sicht (DataView) und den dazugehörenden BindingManager. Wenn man durchgängig dasselbe BindingSource Objekt nutzt. kann man mit dem Aufruf von EndEdit beim BindingSource Objekt das Beenden des Editvorganges in den an das BindingSource Oblekt gebundenen Steuerelementen sicher erreichen.

    --
    Peter 

    Dienstag, 20. August 2013 19:31
  • Hallo Peter ,

    Ich werd mich bei Zeit mal belesen dazu. Ist WPF mittlerweile soweit aus den Kindershuhen raus , das man es effektiv nutzen kann ? Mein letzter Versuch war 2009 / 2010 und da gingn irgendwie noch nicht viel.

    Ist das DGV dort gleich oder einfacher für solche Probleme ?

    Donnerstag, 22. August 2013 07:10
  • Hi Florian,
    zum DataGrid in WPF ist nur zu vermerken, dass es da viel mehr Möglichkeiten der Darstellung gibt als mit den klassischen Windows DataGrid und DataGridView. Die Bindung im WPF DataGrid kann organisiert werden mit einer Klasse, die ICollectionView implementiert. Das kann beispielsweise die View-Eigenschaft einer CollectionViewSource sein. Als Datenquelle für die CollectionViewSource kann eine Vielzahl von Objekten genutzt werden, die Datenobjekte in Form von Listen bereitstellen. Vereinfacht kann man eine ICollectionView mit einer DataView und die CollectionViewSource mit einer BindingSource vergleichen. Die darin ablaufenden Prozesse der Sortierung und Filterung sind ähnlich gelöst.

    --
    Peter

    Sonntag, 25. August 2013 06:00