Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Ebbene si, a volte sono testardo, e su questo problema mi ci sono puntato.
Voglio creare una classe AutoSortableObservableCollection(Of T), e ho pensato di ereditare dall'observable semplice, aggiungengo una procedura Sort() che ordinando una List(Of T) creata dalla collezione.ToList(), ricavi gli indici degli elementi ordinati in quest'ultima utilizzando il Comparer Generico, e riordini la collezione.
ByVal e As System.Collections.Specialized.NotifyCollectionChangedEventArgs) _
HandlesMe.CollectionChanged
Try
If _AutoSort Then Sort()
Catch ex As Exception
MessageBox.Show(ex.Message)
EndTry
EndSub
non funziona, e mi tocca fare .Sort dall'esterno,
il problema è che quando chiamo la prima volta la procedura Sort, mi mostra gli elementi in un determinato ordine, quando poi faccio un'aggiunta (con .Add) e richiamo Sort, mi distribuisce gli elementi in un'altro ordine, che non poi non cambia negli ordinamenti successivi. Salvo la collezione su file, la ricarico, l'ordine è quello del primo Sort.
Perfavore, aiutatemi a capire
P.S. se volete un piccolo progetto di esempio ve lo prepare e lo allego, ma ho assolutamente bisogno di comprendere il problema
GRAZIE
Ultima modifica effettuata da dedalux il 29/12/2010 alle 16:25
quello che continua a sfuggirti è che NON puoi fare il sorting di una collection generica all'infuori di un sort generale basato sul comparer di default in quanto NON sai il tipo degli elementi che ci sono dentro NE' su cosa ordinare.
L'unico modo per fare quello che vuoi fare è imporre al tipo degli elementi della collection di ereditare da una classe/interfaccia che esponga qualcosa come un campo o un comparer su cui basare il sort.
non so ci andrei comunque cauto... dipende dall'ordine di grandezza che consideri.... comunque sono discorsi abbastanza filosofici... al dilà di questo è notevole leggere su questo forum dei concetti di questa levatura... come prossimo passaggio ti consiglio di passare a un linguaggio un pò meno fumoso o fuffoso magari c#
Grazie HeDo per la risposta.
Sarà la mancanza di sonno delle vacanze, ma non ho capito cosa intendi con "all'infuori"..
Da quello che hai scritto capisco che la soluzione che proponi sarebbe far implementare IComparable (http://msdn.microsoft.com/it-it/library/ey2t2ys5.aspx) a qualsiasi classe io voglia usare al posto di T, per poter esporre il metodo CompareTo
ma il problema è che il metodo CompareTo può basarsi solo su una proprietà, come faccio se la proprietà la deve scegliere l'utente...? ç_ç
Senza contare che fare questo lavoro per ogni classe non è certo poco lavoro...
Secondo me una soluzione c'è!
Se l'hai capita, non è che potresti graziarmi?
Ultima modifica effettuata da dedalux il 29/12/2010 alle 17:26
Ciao, secondo ti sfugge il problema di fondo... se la lista contiene N elementi T Generici...con quale criterio li ordini, se assumi il fatto che siano stringhe o numeri è inutile che usi l'oggetto T comunque... per ordinare le liste.. LinqToObject, nessun ciclo 1 riga di codice .OrderBy(X=>X.Property).ToList(),
se invece il tuo oggetto può contenere un T primitivo puoi prevedere degli ordinamenti di default in base al tuo T primitivo.
Gianluca, non vedo in che modo possa influire la quantità N di elementi da ordinare, se non in termini di tempo.
Comunque la collezione (che non è una lista) contiene elementi T che NON sono tipi primitivi, ma classi, e l'ordinamento di queste deve avvenire in base ad una proprietà scelta a runtime (tra quelle della classe).
Quello che mi proponi te se ho ben capito, è un'espressione Lamba, che in VB.NET, nel mio caso, sarebbe da tradurre così
Codice sorgente - presumibilmente C# / VB.NET
Dim me2 = Me.ToList.OrderBy(Function(f As T) f.Proprietà)'.ThenBy ...
e poi fare anche qui una cosa di questo genere
Codice sorgente - presumibilmente VB.NET
me2.Sort(New Comparison(Of T) _
(Function(t1 As T, t2 As T) TipoDellaProprietà.Compare(t1.Proprietà, t2.Proproetà)))
ForEach tObj As TIn me2
Me.Move(Me.IndexOf(tObj), me2.IndexOf(tObj))
Next
ed il risultato non è diverso
Ultima modifica effettuata da dedalux il 29/12/2010 alle 18:07
Grazie HeDo per la risposta.
Sarà la mancanza di sonno delle vacanze, ma non ho capito cosa intendi con "all'infuori"..
Da quello che hai scritto capisco che la soluzione che proponi sarebbe far implementare IComparable (http://msdn.microsoft.com/it-it/library/ey2t2ys5.aspx) a qualsiasi classe io voglia usare al posto di T, per poter esporre il metodo CompareTo
ma il problema è che il metodo CompareTo può basarsi solo su una proprietà, come faccio se la proprietà la deve scegliere l'utente...? ç_ç
Senza contare che fare questo lavoro per ogni classe non è certo poco lavoro...
Secondo me una soluzione c'è!
Se l'hai capita, non è che potresti graziarmi?
la proprietà scelta dall'utente viene infatti specificata all'interno dell'implementazione personalizzata di CompareTo infatti al suo interno la classe provvederà a stabilire il rapporto d'ordine con un'altra classe, in base ad un criterio personalizzato.
Mi dai l'idea di avere in mente la soluzione, siccome così non la capisco molto non è che potresti entrare in chat che ne parliamo un'attimino?
Grazie HeDo
così su due piedi:
Codice sorgente - presumibilmente C#
class AutoSortableObservableCollection<T>: ObservableCollection<T>
{
public Comparison<T> Comparer { get; set;}
publicvoid Sort()
{
T[] temp =this.Items.ToArray<T>();
Array.Sort<T>(temp, Comparer);
this.Items.Clear();
foreach(var item in temp)
this.Items.Add(item);
}
}
Comparer è un campo pubblico che rappresenta il comparatore degli elementi, può essere specificato a runtime e modifica dinamicamente l'ordinamento degli elementi.