none
Gebundenes DataGridView über mehrer Spalten sortieren RRS feed

  • Frage

  • Ich bin auf der Suche nach einer Lösung, wie ich die Anzeige eines DGVs über mehrer Spalten programatisch sortieren kann.

    Eine Sortierung der zugrundeliegenden BindingSource ist nicht möglich, dass das DGV verschiedene Spalten von GUIDs in entsprechende Texte umwandelt. Ich möchte dass im DGV nach dem angezeigten Text/Wert sortiert wird.

    Beispiel: die BindingSource hat die Spalten EntryGUID, TypeGUID, Name. Eine Zeile mit Werten sieht daher so aus:

    "840A6FD9-1618-49cc-96CE-C9E719A7528A,EA9A029F-59E2-4cb7-8D2D-1310017E2A29,Bill Gates"

    Im DGV wird aber angezeigt:
    "Kunde | Bill Gates"

    Wenn ich jetzt die BS sortiere, wird alphabetisch nach TypeGUID sortiert. Dies ist aber unter Umständen nicht identisch, mit der alphabetischen Reihenfolger der Werte (Kunde, Freund, Mitarbeiter, Lebenspartner ....)

    Ich hab ein paar Lösungen gefunden, die aber immer nur in Verbindung mit UNGEBUNDENEN DGVs funktionieren. Ich benötige hier aber eine Lösung für das gebunden DGV

    Donnerstag, 16. Dezember 2010 07:40

Antworten

  • Hallo,

    Ich bin auf der Suche nach einer Lösung, wie ich die Anzeige eines
    DGVs über mehrer Spalten programatisch sortieren kann.

        Dim DV as DataView = DirectCast(DGV.DataSource, DataView)
        DV.Sort = "Feld1, Feld2, Feld3"

    Eine Sortierung der zugrundeliegenden BindingSource ist nicht
    möglich, dass das DGV verschiedene Spalten von GUIDs in
    entsprechende Texte umwandelt.

    Wie (Code) wandelst Du was in Texte um?

    Ich möchte dass im DGV nach dem angezeigten Text/Wert sortiert wird.

    Die eigentliche Sortierung erfolgt wie oben gezeigt in der
    als DataSource dienenden DataView.

    Beispiel: die BindingSource hat die Spalten EntryGUID,
    TypeGUID, Name. Eine Zeile mit Werten sieht daher so aus:

    "840A6FD9-1618-49cc-96CE-C9E719A7528A,
     EA9A029F-59E2-4cb7-8D2D-1310017E2A29,
     Bill Gates"

    Im DGV wird aber angezeigt:
    "Kunde | Bill Gates"

    Wie (Code) wird die Anzeige "Kunde" erzeugt?

    Wenn ich jetzt die BS sortiere, wird alphabetisch nach
    TypeGUID sortiert.

    Wie sieht denn Deine Anweisung

        BindingSource.Sort = .....

    konkret aus?

    Dies ist aber unter Umständen nicht identisch, mit der alphabetischen
    Reihenfolger der Werte (Kunde, Freund, Mitarbeiter, Lebenspartner ....)

    Ich hab ein paar Lösungen gefunden, die aber immer nur in
    Verbindung mit UNGEBUNDENEN DGVs funktionieren.
    Ich benötige hier aber eine Lösung für das gebunden DGV

    Hier mal ein Beispiel, bei dem die Anzeige in einem DGV nach
    3 Spalten sortiert wird.
    Kopiere nachfolgenden Code in ein leeres Formmodul Form1.vb.

    ' / / /  Beginn Code Form1.vb
    Public Class Form1
        Private WithEvents DGV As DataGridView
        Private WithEvents btnSort As Button
        Private mDT As DataTable
        Private WithEvents mBS As BindingSource
        Private BtnText(1) As String

        Private Sub Form1_Load _
                (ByVal sender As System.Object, _
                 ByVal e As System.EventArgs _
                ) Handles MyBase.Load

            Me.ClientSize = New Size(400, 360)

            BtnText(0) = "Sort"
            BtnText(1) = "UnSort"

            CreateControls()
        End Sub

        Private Sub Form1_Shown _
                (ByVal sender As Object, _
                 ByVal e As System.EventArgs _
                ) Handles Me.Shown

            CreateData()

            ' DGV via mBS an DataTable (mDT) binden.
            DGV.DataSource = mBS.List

            DGV.Columns(0).DefaultCellStyle.Alignment = _
                    DataGridViewContentAlignment.MiddleRight

            DGV.AutoResizeColumns()
        End Sub

        Private Sub CreateControls()
            btnSort = New Button
            With btnSort
                .Name = "btnSort"
                .Font = New Font("Arial", 10)

                .SetBounds _
                        (Me.ClientSize.Width - 100, _
                         Me.ClientSize.Height - 50, _
                         90, 40)

                .Anchor = _
                        AnchorStyles.Right Or _
                        AnchorStyles.Bottom

                .Text = BtnText(0)
            End With
            Me.Controls.Add(btnSort)

            DGV = New DataGridView
            With DGV
                .Name = "DGV"

                .SetBounds _
                        (10, 10, _
                         Me.ClientSize.Width - 20, _
                         Me.ClientSize.Height - 70)

                .DefaultCellStyle.Font = _
                        New Font("Arial", 12)

                .ColumnHeadersDefaultCellStyle.Font = _
                        New Font("Arial", 8, FontStyle.Bold)

                .Anchor = _
                        AnchorStyles.Left Or _
                        AnchorStyles.Top Or _
                        AnchorStyles.Right Or _
                        AnchorStyles.Bottom
            End With
            Me.Controls.Add(DGV)
        End Sub

        Private Sub CreateData()
            Dim i As Integer
            Dim DR As DataRow
            Dim DC As DataColumn

            mDT = New DataTable("mDT")
            With mDT
                DC = .Columns.Add("ID", GetType(Integer))
                DC.Unique = True
                DC.AllowDBNull = False

                .Columns.Add("Nachname", GetType(String))
                .Columns.Add("Vorname", GetType(String))
                .Columns.Add("Ort", GetType(String))
            End With

            AddEntry(mDT, 1, "Meier", "Hans", "München")
            AddEntry(mDT, 2, "Meier", "Lisa", "München")
            AddEntry(mDT, 3, "Berger", "Rosa", "Stuttgart")
            AddEntry(mDT, 4, "Schneider", "Herbert", "Berlin")
            AddEntry(mDT, 5, "Meier", "Josef", "Passau")
            AddEntry(mDT, 6, "Schneider", "Herbert", "Köln")
            AddEntry(mDT, 7, "Meier", "Hans", "Augsburg")
            AddEntry(mDT, 8, "Schröder", "Fritz", "Berlin")
            AddEntry(mDT, 9, "Müller", "Helga", "Düsseldorf")
            AddEntry(mDT, 10, "Schröder", "Anna", "Berlin")

            mBS = New BindingSource
            mBS.DataSource = mDT
        End Sub

        Private Sub AddEntry _
                (ByVal DT As DataTable, _
                 ByVal ID As Integer, _
                 ByVal VorName As String, _
                 ByVal NachName As String, _
                 ByVal Ort As String)

            Dim dr As DataRow = DT.NewRow
            dr(0) = ID
            dr(1) = VorName
            dr(2) = NachName
            dr(3) = Ort
            DT.Rows.Add(dr)
        End Sub

        Private Sub btnSort_Click _
                (ByVal sender As Object, _
                 ByVal e As System.EventArgs _
                ) Handles btnSort.Click

            If btnSort.Text = BtnText(0) Then
                ' Sortieren
                mBS.Sort = "NachName, VorName, Ort ASC"
                btnSort.Text = BtnText(1)
            Else
                ' Sortierung aufheben
                mBS.Sort = ""
                btnSort.Text = BtnText(0)
            End If
        End Sub
    End Class
    ' \ \ \  E N T E

    Nach dem Programmstart siehst Du die Form1 mit einem
    DataGridView (DGV) sowie einem Button (btnSort).
    Ein Klick auf den Button sortiert den Inhalt des DGV nach
    den Spalten NachName, VorName, Ort. Ein weiterer
    Klick auf den Button hebt diese Sortierung wieder auf usw.

    Das DGV ist hierbei über eine BindingSource (mBS) an
    die DataTable (mDT) gebunden.

    Gruß aus St.Georgen
    Peter Götz
    www.gssg.de (mit VB-Tipps u. Beispielprogrammen)

    Donnerstag, 16. Dezember 2010 09:47
  • Ich löse solch Problem, indem ich die Text-Info aus dem Master in einer zusätzliche Eigenschaft bereitstelle (“dupliziere”) und danach sortiere. Wenn Du mit DataTables arbeitest, kann man die Nachschlagespalte (Master-Tabelle) über Relation in einem DataSet ablegen und dann eine Ausdrucksspalte der eigentlichen Tabelle (Child-Tabelle) hinzufügen, die auf Parent verweist und nach der sortiert wird.
     
    --
    Viele Grüße
    Peter
    Donnerstag, 16. Dezember 2010 13:40

Alle Antworten

  • Hallo,

    Ich bin auf der Suche nach einer Lösung, wie ich die Anzeige eines
    DGVs über mehrer Spalten programatisch sortieren kann.

        Dim DV as DataView = DirectCast(DGV.DataSource, DataView)
        DV.Sort = "Feld1, Feld2, Feld3"

    Eine Sortierung der zugrundeliegenden BindingSource ist nicht
    möglich, dass das DGV verschiedene Spalten von GUIDs in
    entsprechende Texte umwandelt.

    Wie (Code) wandelst Du was in Texte um?

    Ich möchte dass im DGV nach dem angezeigten Text/Wert sortiert wird.

    Die eigentliche Sortierung erfolgt wie oben gezeigt in der
    als DataSource dienenden DataView.

    Beispiel: die BindingSource hat die Spalten EntryGUID,
    TypeGUID, Name. Eine Zeile mit Werten sieht daher so aus:

    "840A6FD9-1618-49cc-96CE-C9E719A7528A,
     EA9A029F-59E2-4cb7-8D2D-1310017E2A29,
     Bill Gates"

    Im DGV wird aber angezeigt:
    "Kunde | Bill Gates"

    Wie (Code) wird die Anzeige "Kunde" erzeugt?

    Wenn ich jetzt die BS sortiere, wird alphabetisch nach
    TypeGUID sortiert.

    Wie sieht denn Deine Anweisung

        BindingSource.Sort = .....

    konkret aus?

    Dies ist aber unter Umständen nicht identisch, mit der alphabetischen
    Reihenfolger der Werte (Kunde, Freund, Mitarbeiter, Lebenspartner ....)

    Ich hab ein paar Lösungen gefunden, die aber immer nur in
    Verbindung mit UNGEBUNDENEN DGVs funktionieren.
    Ich benötige hier aber eine Lösung für das gebunden DGV

    Hier mal ein Beispiel, bei dem die Anzeige in einem DGV nach
    3 Spalten sortiert wird.
    Kopiere nachfolgenden Code in ein leeres Formmodul Form1.vb.

    ' / / /  Beginn Code Form1.vb
    Public Class Form1
        Private WithEvents DGV As DataGridView
        Private WithEvents btnSort As Button
        Private mDT As DataTable
        Private WithEvents mBS As BindingSource
        Private BtnText(1) As String

        Private Sub Form1_Load _
                (ByVal sender As System.Object, _
                 ByVal e As System.EventArgs _
                ) Handles MyBase.Load

            Me.ClientSize = New Size(400, 360)

            BtnText(0) = "Sort"
            BtnText(1) = "UnSort"

            CreateControls()
        End Sub

        Private Sub Form1_Shown _
                (ByVal sender As Object, _
                 ByVal e As System.EventArgs _
                ) Handles Me.Shown

            CreateData()

            ' DGV via mBS an DataTable (mDT) binden.
            DGV.DataSource = mBS.List

            DGV.Columns(0).DefaultCellStyle.Alignment = _
                    DataGridViewContentAlignment.MiddleRight

            DGV.AutoResizeColumns()
        End Sub

        Private Sub CreateControls()
            btnSort = New Button
            With btnSort
                .Name = "btnSort"
                .Font = New Font("Arial", 10)

                .SetBounds _
                        (Me.ClientSize.Width - 100, _
                         Me.ClientSize.Height - 50, _
                         90, 40)

                .Anchor = _
                        AnchorStyles.Right Or _
                        AnchorStyles.Bottom

                .Text = BtnText(0)
            End With
            Me.Controls.Add(btnSort)

            DGV = New DataGridView
            With DGV
                .Name = "DGV"

                .SetBounds _
                        (10, 10, _
                         Me.ClientSize.Width - 20, _
                         Me.ClientSize.Height - 70)

                .DefaultCellStyle.Font = _
                        New Font("Arial", 12)

                .ColumnHeadersDefaultCellStyle.Font = _
                        New Font("Arial", 8, FontStyle.Bold)

                .Anchor = _
                        AnchorStyles.Left Or _
                        AnchorStyles.Top Or _
                        AnchorStyles.Right Or _
                        AnchorStyles.Bottom
            End With
            Me.Controls.Add(DGV)
        End Sub

        Private Sub CreateData()
            Dim i As Integer
            Dim DR As DataRow
            Dim DC As DataColumn

            mDT = New DataTable("mDT")
            With mDT
                DC = .Columns.Add("ID", GetType(Integer))
                DC.Unique = True
                DC.AllowDBNull = False

                .Columns.Add("Nachname", GetType(String))
                .Columns.Add("Vorname", GetType(String))
                .Columns.Add("Ort", GetType(String))
            End With

            AddEntry(mDT, 1, "Meier", "Hans", "München")
            AddEntry(mDT, 2, "Meier", "Lisa", "München")
            AddEntry(mDT, 3, "Berger", "Rosa", "Stuttgart")
            AddEntry(mDT, 4, "Schneider", "Herbert", "Berlin")
            AddEntry(mDT, 5, "Meier", "Josef", "Passau")
            AddEntry(mDT, 6, "Schneider", "Herbert", "Köln")
            AddEntry(mDT, 7, "Meier", "Hans", "Augsburg")
            AddEntry(mDT, 8, "Schröder", "Fritz", "Berlin")
            AddEntry(mDT, 9, "Müller", "Helga", "Düsseldorf")
            AddEntry(mDT, 10, "Schröder", "Anna", "Berlin")

            mBS = New BindingSource
            mBS.DataSource = mDT
        End Sub

        Private Sub AddEntry _
                (ByVal DT As DataTable, _
                 ByVal ID As Integer, _
                 ByVal VorName As String, _
                 ByVal NachName As String, _
                 ByVal Ort As String)

            Dim dr As DataRow = DT.NewRow
            dr(0) = ID
            dr(1) = VorName
            dr(2) = NachName
            dr(3) = Ort
            DT.Rows.Add(dr)
        End Sub

        Private Sub btnSort_Click _
                (ByVal sender As Object, _
                 ByVal e As System.EventArgs _
                ) Handles btnSort.Click

            If btnSort.Text = BtnText(0) Then
                ' Sortieren
                mBS.Sort = "NachName, VorName, Ort ASC"
                btnSort.Text = BtnText(1)
            Else
                ' Sortierung aufheben
                mBS.Sort = ""
                btnSort.Text = BtnText(0)
            End If
        End Sub
    End Class
    ' \ \ \  E N T E

    Nach dem Programmstart siehst Du die Form1 mit einem
    DataGridView (DGV) sowie einem Button (btnSort).
    Ein Klick auf den Button sortiert den Inhalt des DGV nach
    den Spalten NachName, VorName, Ort. Ein weiterer
    Klick auf den Button hebt diese Sortierung wieder auf usw.

    Das DGV ist hierbei über eine BindingSource (mBS) an
    die DataTable (mDT) gebunden.

    Gruß aus St.Georgen
    Peter Götz
    www.gssg.de (mit VB-Tipps u. Beispielprogrammen)

    Donnerstag, 16. Dezember 2010 09:47
  • Wie (Code) wird die Anzeige "Kunde" erzeugt?

    Danke für dein Beispiel. So wie du es beschrieben hast, funktioniert es. Aber bei mir sind die zugrundeliegenden Daten ebenn GUIDs und nicht der anzuzeiugenden Text

    Die Spalte, die den "Text" statt der GUID anzeigt, ist eine "DataGridViewComboBoxColumn". Diese wird zuvor aus der Datenbank dynamisch gefüllt und auch gebunden:

    with dgvColumnNameType
        .ValueMember = "NameTypeGUID"
        .DisplayMember = "NameTypeText"
        .DataSource = GetNameTypes
    end with 

    Das funktioniert hervorangend - Nur die Sortierung halt nicht, da die BindingSource des DGVs ja GUIDs zum Sortieren hat und nicht die Texte

    Donnerstag, 16. Dezember 2010 12:02
  • Ich löse solch Problem, indem ich die Text-Info aus dem Master in einer zusätzliche Eigenschaft bereitstelle (“dupliziere”) und danach sortiere. Wenn Du mit DataTables arbeitest, kann man die Nachschlagespalte (Master-Tabelle) über Relation in einem DataSet ablegen und dann eine Ausdrucksspalte der eigentlichen Tabelle (Child-Tabelle) hinzufügen, die auf Parent verweist und nach der sortiert wird.
     
    --
    Viele Grüße
    Peter
    Donnerstag, 16. Dezember 2010 13:40
  • Hallo,

    Wie (Code) wird die Anzeige "Kunde" erzeugt?

    Danke für dein Beispiel. So wie du es beschrieben hast,
    funktioniert es. Aber bei mir sind die zugrundeliegenden
    Daten ebenn GUIDs und nicht der anzuzeiugenden Text

    Das beantwortet aber nicht meine obige Frage.

    Die Spalte, die den "Text" statt der GUID anzeigt, ist eine
    "DataGridViewComboBoxColumn". Diese wird zuvor aus
    der Datenbank dynamisch gefüllt und auch gebunden:

    with dgvColumnNameType
    .ValueMember = "NameTypeGUID"
    .DisplayMember = "NameTypeText"
    .DataSource = GetNameTypes
    end with

    Wer oder was ist GetNameTypes?

    Wie sieht die DataTable, an welche das DataGridView
    gebunden ist konkret aus (Spalten, Datentypen)?

    Das funktioniert hervorangend - Nur die Sortierung halt
    nicht, da die BindingSource des DGVs ja GUIDs zum
    Sortieren hat und nicht die Texte.

    Ohne die wirkliche Struktur Deiner DataTables (Datenquellen
    für das DGV und Datenquelle für die ComboBox) zu kennen,
    ist nicht ersichtlich, wo Dein Problem liegt und wie eine
    Lösung konkret aussehen könnte.

    Gruß aus St.Georgen
    Peter Götz
    www.gssg.de (mit VB-Tipps u. Beispielprogrammen)

    Donnerstag, 16. Dezember 2010 20:51