Frage

Ich möchte eine ObservableCollection alphabetisch bestellen, weil ich keine weitere Bindung erstellen möchte.Ich habe gesehen, dass wir Linq und die Methode OrderBy verwenden könnten.Ich möchte auch einen persönlichen IComparer verwenden, da ich komplexe Daten (Listen in anderen Listen) organisieren muss, aber VS sagt mir, dass ich meinen eigenen Vergleicher nicht verwenden kann :

(gib dir den Link des Fehlers, weil mein VS auf Französisch ist)

http://msdn.microsoft.com/en-gb/library/hxfhx4sy%28v=vs.90%29.aspx

Irgendwelche Ideen ?

private void SortGraphicObjectsAscending(object sender, RoutedEventArgs e)
    {
        GraphicObjects.OrderBy(graphicObject => graphicObject.Nom, new GraphicObjectComparer(true));

    }

Und mein eigener Vergleicher (der bereits getestet wurde)

public class GraphicObjectComparer : IComparer<GraphicObject>
{
    int order = 1;

    public GraphicObjectComparer(Boolean ascending)
    {
        if (!ascending)
        {
            order = -1;
        }
    }

    public GraphicObjectComparer()
    {

    }

    public int Compare(GraphicObject x, GraphicObject y)
    {
        return String.Compare(x.Nom, y.Nom, false) * order;
    }

}

Danke für deine Antworten.Jedenfalls habe ich ein anderes Problem.Wie Michael sagte, verwende ich einen komplexeren Vergleicher, aber für eine andere Entität.Diese Entität wird mit einem hierarchischen Baum angezeigt, und ein Objekt kann eine Liste anderer Objekte desselben Typs enthalten.

Ich konnte mein Grafikobjekt nicht testen, da ich keinen Zugriff auf die Datenbank habe (im Moment gab es kein Objekt).Bei den Tests auf meiner Videoentität scheint meine ObservableCollection nicht so sortiert zu sein, wie ich es möchte (ich erstelle eine andere).Ich möchte es alphabetisch umkehren, aber es funktioniert nicht.

public class VideoEntityComparer : IComparer<VideoEntity>
{

    int order = 1;

    public VideoEntityComparer(Boolean ascending)
    {
        if (!ascending)
        {
            this.order = -1; // so descending
        }
    }

    public VideoEntityComparer()
    {

    }

    public int Compare(VideoEntity x, VideoEntity y)
    {
        if ((x is BaseDirectory && y is BaseDirectory) || (x is BaseSite && y is BaseSite) || (x is VideoEncoder && y is VideoEncoder))
        {
            return string.Compare(x.Nom, y.Nom, false) * order; // only objects of the same type are sorted alphabetically
        }
        else if ((x is BaseDirectory && y is BaseSite) || (x is BaseSite && y is VideoEncoder))
        {
            return -1;
        }else
        {
            return 1;
        }
    }
}

private void SortDirectoriesDescending(object sender, RoutedEventArgs e)
    {
        ObservableCollection<BaseDirectory> tempDir  = new ObservableCollection<BaseDirectory>(
            Directories.OrderBy(directory => directory, new VideoEntityComparer(false)));
        Directories = tempDir;
    }

PS :übrigens, ich handle in einer Abhängigkeitsimmobilie.Ist es der richtige Weg, es zu tun?(Ich bin neu bei WPF)

War es hilfreich?

Lösung

Das Problem mit dieser Zeile liegt in der Definition von OrderBy das du versuchst zu benutzen:

public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector,
    IComparer<TKey> comparer
)

Für diese Methode gibt es zwei verschiedene generische Parameter: TSource und TKey. TSource ist offensichtlich, es ist das gleiche wie das TSource für die Quelle IEnumerable.Der TKey parameter ist derjenige, den der Compiler versucht und den er nicht ableiten kann, weil Sie versuchen, zwei verschiedene Typen zu verwenden.Ihr Anruf:

GraphicObjects.OrderBy(graphicObject => graphicObject.Nom, new GraphicObjectComparer(true));

Ihr erster Parameter ist a Func<GraphicObject, string> aber dein zweiter Parameter ist ein IComparer<GraphicObject>;dies bedeutet, dass Sie verwenden TKey = string an einem Ort und TKey = GraphicObject in der anderen.

Der erste Parameter, der Func<> delegat, ist der "Schlüsselwähler";so erzählst du es OrderBy nach welchen Werten sortiert werden soll.Seit Ihrem IComparer<> basiert die Sortierung auf der gesamte GraphicObject Instanz, das sollten Sie als Ihren Schlüssel auswählen:

GraphicObjects.OrderBy(go => go, new GraphicObjectComparer(true));

Ich gehe davon aus, dass Ihr benutzerdefiniertes Vergleichsobjekt tatsächlich komplexer ist als das, was Sie gezeigt haben, da Ihr Beispielvergleicher ziemlich redundant ist:

var asc = GraphicObjects.OrderBy(go => go.Nom);
var desc = GraphicObjects.OrderByDescending(go => go.Nom);

Beachten Sie auch, dass Ihr Beispielcode mit der neu sortierten Liste eigentlich nichts zu tun hat, sodass er einfach weggeworfen wird.LINQ-Operationen nie ändern Sie die aufzählbare Quelle, sie geben stattdessen immer eine neue, transformierte Kopie davon zurück.

Andere Tipps

Ihrer comparer vergleichen GraphicObject.also dein OrderBy sollte sein

 GraphicObjects.OrderBy(graphicObject => graphicObject,
                                                 new GraphicObjectComparer(true));

oder einfach benutzen

GraphicObjects.OrderBy(graphicObject => graphicObject.Nom);

ÜBRIGENS, OrderBy sortiert nicht direkt, Sie sollten die zurückgegebenen zuweisen IEnumerable<GraphicsObject> zu einer Variablen

Das Problem ist, dass Ihr Komparierer GraphicObject verwendet, aber Sie vergleichen Saiten.

Wenn Sie wirklich Ihre eigene Bestellung benötigen, können Sie diesen Vergleicher verwenden: generasacodicetagpre.

oder Sie geben ein GraphicObject an Ihren Vergleicher an, keine Zeichenfolge.

Um eine sortierende Sortiercollection zu sortieren, reflektiert alle Änderungen in der Quellkollektion, die Sie verwenden können, die Sie verwenden können.Mit dieser Bibliothek können Sie so codieren: generasacodicetagpre.

sortiergraphicobjects ist eine Beobachtungsansicht und spiegelt alle Änderungen in der GraphicObjects-Sammlung und der NOM-Eigenschaft wider.Stellen Sie sicher, dass NOM-Eigenschaft von Änderungen über die InotifyPropertyChanged -Schnittstelle.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top