Domanda

Voglio ordinare in ordine alfabetico ObservableCollection perché non voglio creare un'altra associazione.Ho visto che abbiamo potuto utilizzare Linq e il metodo OrderBy.Vorrei anche usare un IComparer perché dovrò organizzare complesso di dati (liste nelle altre liste), ma VS mi dice che non posso usare la mia operatore di confronto :

(dare il link dell'errore, perché il mio VS è in francese)

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

Tutte le idee ?

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

    }

E il mio operatore di confronto (che è già testato)

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;
    }

}

Grazie per le vostre risposte.Comunque ho un altro problema.Come Michael ha detto, io uso un più complesso il confronto, ma per un'altra entità.Questa entità viene visualizzato con una struttura gerarchica, ed un oggetto che può contenere un elenco di altri oggetti dello stesso tipo.

Ho potuto testare il mio GraphicObject becuse non ho accesso al DB (che non c'era oggetto al momento).Con il test sulla mia VideoEntity sembra che il mio ObservableCollection non è ordinato come voglio io (ho creato un altro).Voglio invertire, in ordine alfabetico, ma non funziona.

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 :a proposito, sto agendo su un DependancyProperty.È il modo corretto per farlo ?(Io sono nuovo su WPF)

È stato utile?

Soluzione

Il problema è la definizione di OrderBy che si sta tentando di utilizzare:

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

Ci sono due diversi parametri generici per questo metodo: TSource e TKey. TSource è ovvio, è lo stesso come il TSource per l'origine IEnumerable.Il TKey parametro è quello che il compilatore cerca, e in mancanza, di dedurre perché si sta tentando di utilizzare due tipi diversi.La chiamata:

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

Il primo parametro è un Func<GraphicObject, string> ma il secondo parametro è un IComparer<GraphicObject>;questo significa che si sta utilizzando TKey = string in un luogo e TKey = GraphicObject negli altri.

Il primo parametro, il Func<> delegato, è il "tasto di selezione";è come dire OrderBy i valori da ordinare.Dal momento che il IComparer<> è l'ordinamento in base al tutto GraphicObject istanza, che cosa si dovrebbe essere selezionando la chiave:

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

Sto supponendo che il vostro uso di questo oggetto è in realtà più complesso di quello che hai mostrato, perché il campione del confronto è piuttosto ridondante:

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

Inoltre, si noti che il codice di esempio, in realtà non fare nulla con il neo-elenco ordinato, in modo che solo ottenere buttato fuori.LINQ operazioni mai cambiare la sorgente di enumerabile, restituiscono sempre una nuova, trasformata copia di esso, invece.

Altri suggerimenti

il comparer confronta GraphicObject.così il vostro OrderBy dovrebbe essere

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

o semplicemente utilizzare

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

BTW, OrderBy non ordina posto, si deve assegnare il restituiti IEnumerable<GraphicsObject> per una variabile

Il problema è che il Programma utilizza GraphicObject, ma è possibile confrontare le stringhe.

Se si ha realmente bisogno di un tuo ordine, è possibile utilizzare questo operatore di Confronto:

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

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

    public GraphicObjectComparer()
    {

    }

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

O si fornisce un GraphicObject al tuo operatore di confronto, non una stringa.

Per ordinato ObservableCollection riflette tutte le modifiche nella raccolta di origine, è possibile utilizzare il mio ObservableComputations biblioteca.Utilizzando questa libreria è possibile un codice come questo:

var sortedGraphicObjects = GraphicObjects.Ordering(
    graphicObject => graphicObject.Nom, new GraphicObjectComparer(true));

sortedGraphicObjects è ObservableCollection e riflette tutte le modifiche in GraphicObjects raccolta e Nom proprietà.Assicurarsi che Nom proprietà notifica di modifiche INotifyPropertyChanged l'interfaccia.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top