none
DataRelation sortieren RRS feed

  • Frage

  • Moin,

    wie kann ich eine BindingListCollectionView aufgrund einer DataColumn aus eine Tabelle, die mit einer DataRelation verbunden ist, sortieren?

    Mit einer GroupDescription funktioniert es wie folgt

    _zeiten.GroupDescriptions.Add(New PropertyGroupDescription("r_Zeiten_Veranstaltungen"))

    mit einer SortDescription funktioniert das aber nicht.

    Ich hoffe ihr könnt mit helfen.

    Gruß HamburgerJungeJr

    Sonntag, 3. August 2014 16:15

Alle Antworten

  • Hallo,

    Du musst schon die Spalte (Name der DataColumn) angeben, die Du sortieren willst, und sie als SortDescription an die SortDescriptions Auflistung anfügen.

    Wenn die Spalte(N) auch Teil einer DataRelation sind, kannst Du die Spalte(n) aus der entsprechenden Auflistung (ChildColumns od. ParentColumns) ermitteln. Wobei das für mich nicht wirklich Sinn gibt, da eine Relation nichts mit der Sortierung zu tun hat.

    Gruß Elmar

    Sonntag, 3. August 2014 17:18
  • Stimmt habe ich nur hier vergessen.

    Es muss so heißen

    _zeiten.GroupDescriptions.Add(New PropertyGroupDescription("r_Zeiten_Veranstaltungen/vDatum"))

    vDatum kommt aber aus einer anderen Tabelle, daher die DataRelation. 

    Wenn ich jetzt aber das so mache:

    _zeiten.SortDescriptions.Add(New SortDescription("r_Zeiten_Veranstaltungen/vDatum",ListSortDirection.Ascending))

    kann ich das Programm nicht mehr starten.

    Sonntag, 3. August 2014 17:45
  • Hallo,

    lasse den Namen der Relation weg und gebe nur die Spalte "vDatum" an.

    Gruß Elmar

    Sonntag, 3. August 2014 20:32
  • Habe ich schon probiert. Dann bekomme ich im Ausgabe-Fenster die Meldung, dass die Spalte vDatum nicht gefunden werden kann.
    Sonntag, 3. August 2014 21:47
  • Hallo,

    wie heißt denn die Spalte auf der anderen Seite?

    Da ich Deinen Tabellenaufbau und die Relation nicht kenne, bleibt mir nichts weiter als raten.

    Gruß Elmar

    Sonntag, 3. August 2014 21:58
  • Das Dataset:

    onedrive.live.com/redir?resid=86BC5AF7AD61689C!233&authkey=!ANxndmSraLCHCoM&v=3&ithint=photo%2cJPGä

    (Ich darf irgendwie keine Bilder hochladen)

    Das ViewModel:

    Imports System.IO
    Imports System.Data
    Imports Technik_Veranstaltungen.dsTechnikVeranstaltungen
    Imports Microsoft.VisualBasic
    Imports Technik_Veranstaltungen.ViewModel
    Imports System.Data.OleDb
    Imports System.ComponentModel
    Imports Technik_Veranstaltungen.ObjectX
    
    Public Class vmMain
        Inherits ViewModelBase
        Private dbPfad As String
        Private WithEvents _veranstaltungen As BindingListCollectionView
        Private WithEvents _anwender As BindingListCollectionView
        Private WithEvents _zeiten As BindingListCollectionView
        Private WithEvents _verfügbar As BindingListCollectionView
        Public Property dsTechnikVeranstaltungen As New dsTechnikVeranstaltungen
        Public ReadOnly Property veranstaltungen() As ICollectionView
            Get
                Return _veranstaltungen
            End Get
        End Property
        Public ReadOnly Property anwender() As ICollectionView
            Get
                Return _anwender
            End Get
        End Property
        Public ReadOnly Property zeiten() As ICollectionView
            Get
                Return _zeiten
            End Get
        End Property
        Public ReadOnly Property verfügbar() As ICollectionView
            Get
                Return _verfügbar.CreateLazy(Function() CType(CollectionViewSource.GetDefaultView(dsTechnikVeranstaltungen.dtVerfügbar), BindingListCollectionView))
            End Get
        End Property
        Public Property ReLoad As New RelayCommand( _
             Sub()
    
             End Sub)
    
        Public Property NewVeranstaltung As New RelayCommand( _
            Sub()
                Dim row As dtVeranstaltungenRow = dsTechnikVeranstaltungen.dtVeranstaltungen.NewdtVeranstaltungenRow
                dsTechnikVeranstaltungen.dtVeranstaltungen.AdddtVeranstaltungenRow(row)
                _veranstaltungen.Refresh()
                _veranstaltungen.MoveCurrentToLast()
            End Sub)
        Public Property Save As New RelayCommand( _
            Sub()
                If dsTechnikVeranstaltungen.HasChanges Then
    
                End If
            End Sub)
        Public Sub New()
            dbPfad = My.Settings.Datenbank
            If Not MyBase.IsInDesignMode Then
                load()
                setSortDescriptions()
            End If
        End Sub
        Private Sub load()
            loadFromDB("SELECT * FROM Veranstaltungen", dsTechnikVeranstaltungen.dtVeranstaltungen)
            loadFromDB("SELECT * FROM Anwender", dsTechnikVeranstaltungen.dtAnwender)
            loadFromDB("SELECT Zeiten.* FROM Veranstaltungen RIGHT JOIN (Zeiten LEFT JOIN Anwender ON Zeiten.zAnwender = Anwender.aId) ON Veranstaltungen.vId = Zeiten.zVeranstaltung ORDER BY Anwender.aNachname, Anwender.aVorname;", dsTechnikVeranstaltungen.dtZeiten)
            loadFromDB("SELECT Verfügbar.* FROM (Verfügbar LEFT JOIN Veranstaltungen ON Verfügbar.vfVeranstaltung = Veranstaltungen.vId) LEFT JOIN Anwender ON Verfügbar.vfAnwender = Anwender.aId ORDER BY Veranstaltungen.vDatum DESC , Anwender.aNachname, Anwender.aVorname;", dsTechnikVeranstaltungen.dtVerfügbar)
        End Sub
        Private Sub loadFromDB(ByVal command As String, ByVal table As DataTable)
            Dim con As New OleDbConnection
            Dim cmd As New OleDbCommand
            con.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & dbPfad & "; Persist Security Info=True;"
            cmd.Connection = con
            Try
                con.Open()
                cmd.CommandText = command
                Dim reader As OleDbDataReader = cmd.ExecuteReader
                table.Load(reader)
                reader.Close()
                con.Close()
            Catch ex As Exception
                MessageBox.Show(ex.Message)
            End Try
        End Sub
        Private Sub setSortDescriptions()
            'Veranstaltungen
            _veranstaltungen = CType(CollectionViewSource.GetDefaultView(dsTechnikVeranstaltungen.dtVeranstaltungen), BindingListCollectionView)
            _veranstaltungen.SortDescriptions.Add(New SortDescription("vDatum", ListSortDirection.Descending))
            _veranstaltungen.MoveCurrentToFirst()
            'Anwender
            _anwender = CType(CollectionViewSource.GetDefaultView(dsTechnikVeranstaltungen.dtAnwender), BindingListCollectionView)
            _anwender.SortDescriptions.Add(New SortDescription("aNachname", ListSortDirection.Ascending))
            _anwender.SortDescriptions.Add(New SortDescription("aVorname", ListSortDirection.Ascending))
            _anwender.MoveCurrentToFirst()
            'Zeiten
            _zeiten = CType(CollectionViewSource.GetDefaultView(dsTechnikVeranstaltungen.dtZeiten), BindingListCollectionView)
    
            '_zeiten.GroupDescriptions.Add(New PropertyGroupDescription("r_Zeiten_Veranstaltungen/vDatum"))
            '_zeiten.SortDescriptions.Add(New SortDescription("@vDatum", ListSortDirection.Descending))
        End Sub
    End Class

    Das XAML:

    <Grid x:Name="g_Zeiten" DataContext="{Binding zeiten}">
                                                <Grid.ColumnDefinitions>
                                                    <ColumnDefinition Width="95" />
                                                    <ColumnDefinition Width="100" />
                                                    <ColumnDefinition Width="18" />
                                                    <ColumnDefinition Width="65" />
                                                    <ColumnDefinition Width="14" />
                                                    <ColumnDefinition Width="65" />
                                                    <ColumnDefinition Width="14" />
                                                    <ColumnDefinition Width="*" />
                                                </Grid.ColumnDefinitions>
                                                <Grid.RowDefinitions>
                                                    <RowDefinition Height="45" />
                                                    <RowDefinition Height="22" />
                                                    <RowDefinition Height="15" />
                                                    <RowDefinition Height="22" />
                                                    <RowDefinition Height="5" />
                                                    <RowDefinition Height="22" />
                                                    <RowDefinition Height="5" />
                                                    <RowDefinition Height="22" />
                                                    <RowDefinition Height="5" />
                                                    <RowDefinition Height="22" />
                                                    <RowDefinition Height="5" />
                                                    <RowDefinition Height="22" />
                                                    <RowDefinition Height="5" />
                                                    <RowDefinition Height="167" />
                                                    <RowDefinition Height="*" />
                                                </Grid.RowDefinitions>
                                                <ComboBox x:Name="c_zAuswahl" Grid.Column="1" Grid.Row="1" Style="{StaticResource comboboxStyle}" Grid.ColumnSpan="6" IsTabStop="False" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding}">
                                                    <ComboBox.ItemTemplate>
                                                        <DataTemplate>
                                                            <StackPanel Orientation="Horizontal">
                                                                <TextBlock Text="{Binding Path=r_Zeiten_Veranstaltungen/vDatum, Converter={StaticResource dateConverter}}" />
                                                                <TextBlock Text=" / " />
                                                                <TextBlock Text="{Binding Path=r_Zeiten_Anwender/aNachname}" />
                                                                <TextBlock Text=", " />
                                                                <TextBlock Text="{Binding Path=r_Zeiten_Anwender/aVorname}" />
                                                                <!--<ComboBox ItemsSource="{Binding Source={StaticResource vmMain}, Path=veranstaltungen}" DisplayMemberPath="vDatum" SelectedValuePath="vId" SelectedValue="{Binding Path=zVeranstaltung}" IsReadOnly="True">
                                                                    <Control.Template>
                                                                        <ControlTemplate TargetType="{x:Type ComboBox}">
                                                                            <TextBlock Text="{TemplateBinding Text, Converter={StaticResource dateConverter}}"/>
                                                                        </ControlTemplate>
                                                                    </Control.Template>
                                                                </ComboBox>
                                                                <TextBlock Text=" / " />
                                                                <ComboBox ItemsSource="{Binding Source={StaticResource vmMain}, Path=anwender}" DisplayMemberPath="aNachname" SelectedValuePath="aId" SelectedValue="{Binding Path=zAnwender}" IsReadOnly="True">
                                                                    <Control.Template>
                                                                        <ControlTemplate TargetType="{x:Type ComboBox}">
                                                                            <TextBlock Text="{TemplateBinding Text}"/>
                                                                        </ControlTemplate>
                                                                    </Control.Template>
                                                                </ComboBox>
                                                                <TextBlock Text=", " />
                                                                <ComboBox ItemsSource="{Binding Source={StaticResource vmMain}, Path=anwender}" DisplayMemberPath="aVorname" SelectedValuePath="aId" SelectedValue="{Binding Path=zAnwender}" IsReadOnly="True">
                                                                    <Control.Template>
                                                                        <ControlTemplate TargetType="{x:Type ComboBox}">
                                                                            <TextBlock Text="{TemplateBinding Text}"/>
                                                                        </ControlTemplate>
                                                                    </Control.Template>
                                                                </ComboBox>-->
                                                            </StackPanel>
                                                        </DataTemplate>
                                                    </ComboBox.ItemTemplate>
                                                </ComboBox>

    Sonntag, 3. August 2014 23:07
  • Hallo,

    Du kannst nur nach Spalten sortieren, die sich in der jeweiligen DataTable befinden, Querbeet über eine DataRelation funktioniert das nicht.

    Und wenn ich Deine Namensvergabe richtig interpretiere, ist vDatum nicht dtZeiten enthalten, somit ist danach nicht sortierbar- selbst dies möglich wäre gäbe es keinen Sinn. Mögliche Sortierkriterien wären z. B. zAnkunft und zEnde. (Ein @ hat bei dem Spaltennamen nichts verloren).

    Unabhängig davon: Sinnvoller wäre für loadFromDB einen OleDbDataAdapter einzusetzen und die Verbindung bereits in  load in einer using Anweisung zu erstellen und zu eröffnen.

    Auch den Einsatz von LEFT / RIGHT JOIN bei den Abfragen solltest Du noch mal prüfen, i. a. ist ein INNER JOIN angemessen.

    Gruß Elmar


    • Bearbeitet Elmar Boye Montag, 4. August 2014 08:32
    Montag, 4. August 2014 08:31
  • Warum gibt das keinen Sinn?? Der Gedanke der Relationen ist doch gerade, dass ich nicht in jeder Tabelle alle Daten speichern muss, die ich mir durch eine Relation aus einer anderen Tabelle holen kann.

    Das @ war nur ein Versuch, da ich alle Möglichkeiten probiert habe, um auf die Spalte zuzugreifen.

    Den OleDb-Adapter werde ich  mir mal ansehen.

    Montag, 4. August 2014 09:03
  • Hallo,

    Eine DataRelation hat eine vergleichbare Funktion wie eine eine Einschränkung, weswegen sie (optional) als ForeignKeyConstraint eingesetzt wird. Mit einer Sortierung hat das gar nichts zu tun.

    Sortiert wird nur die Ausgabe  einer SELECT Anweisung.

    Eine Sortierung kann (in SQL) nur auf Ausgabe-Spalten angewendet werden. Deine Abfrage liefert aber nur Werte aus der Zeiten Tabelle. Auch bei einer DataTable kann eine Sortierung nur auf Spalten in der DataTable angewendet werden.

    Zudem, wozu sollte eine Sortierung einer äußeren Tabelle gut sein? Der gleiche Wert kann 1 .. N mal vorkommen; ohne eine Sortierung auf (mindestens) einer der Tabellenspalten wäre der Inhalt nur teilsortiert.

    Eine Relation wiederum wird auch als Filter verwendet, wodurch dann nur die Daten der Verknüpfung angezeigt werden, siehe z. B.: Parent/Child DataRelation. The Basics.

    und Einführung in DataRelation-Objekte

    Gruß Elmar


    • Bearbeitet Elmar Boye Montag, 4. August 2014 09:16 Link
    Montag, 4. August 2014 09:15
  • Ich brauche die Sortierung zur Anzeige in einer Combobox. Die Tabelle Zeiten beinhaltet Arbeitszeiten. Diese Combobox möchte ich zuerst nach dem Datum aus der Tabelle Veranstaltungen und dann nach den Namen sortieren.
    Montag, 4. August 2014 09:37
  • Hallo,

    wie aus meinen bisherigen Ausführungen zu entnehmen sein sollte, musst Du dann die Spalte in die Abfrage / DataTable aufnehmen.

    Gruß Elmar

    Montag, 4. August 2014 18:00