Skip to content

Forum

Please or Register to create posts and topics.

TreeView, TreeViewItems e DataTemplate

Ciao

Sto cercando di popolare un treeview con dati forniti da un DBcontext di EF.

Per ora ci sono tre tabelle/entity in gioco che per lo scopo del post chiamerò Persone, Amici, Indirizzi. Quindi, una persona puo' avere tanti Amici e tanti Indirizzi.

Il treeview dovrebbe avere una rappresentazione simile a questa

Mario              -> classe persona

|-Amici           -> ObservableCollection<amico>

|    |----Gino  -> classe amico

|    |----Luigi -> classe amico

|-Indirizzi     -> ObservableCollection<indirizzo>

|-Casa        -> classe indirizzo

|-Ufficio    -> classe indirizzo

Amici e Indirizzi sono delle ObservableCollection<T> della classe Persona i cui rispettivi T sono completamente diversi.

I problemi principali sono 2. Amici e Indirizzi non sono degli Item contenuti in una collezione di Persona, ma sono proprio delle collezioni e quindi non so come creare un HierarchicalDataTemplate che mi crei i due nodi Amici e Indirizzi.

Secondo problema, gli Item di indirizzi e gli Item di amici hanno una struttura completamente diversa. Quindi non posso usare lo stesso template per rappresentarli nel Treeview.

Ho cercato di affrontare il problema usando diverse strategie ma nessuna mi e' sembrata né concludente né elegante.

Prima soluzione - Popolare il Treeview da codice

Popolarlo e' stato facile pero' non sono riuscito ad assegnare un DataTemplate via xaml al singolo nodo aggiunto da codice. Usando un TemplateSelector ricevevo degli errori di Item già esistente nel Treeview (ora non ricordo l'errore preciso). Prima di impantanarmi con DependencyObjects e binding creati via codice ho preferito testare anche la soluzione via xaml

Seconda soluzione - Popolare il TreeView da XAML

Con un HierachicalDataTemplate e un TemplateSelector sono riuscito a popolare il TreeView ma il risultato e' stato:

Mario           -> PersonaTemplate

|----Gino     -> AmicoTemplate

|----Luigi

Perdendo quindi il nodo Amici ed impossibilitato ad aggiungere tutti gli indirizzi in quanto appartenenti ad una altra OC e quindi non potendo usare contemporaneamente 2 HierarchicalDataTemplate per lo stesso nodo.

Ad occhio direi che dovrei creare una classe intermedia "ItemsdiPersona". Quindi in Persona aggiungere una OC<ItemsdiPersona> Items .

In "ItemsdiPersona" in cui aggiungere una OC<object> per inserirci le OC<amico> e OC<indirizzo>.

Poi creare un  HierarchicalDataTemplate per ogni OC

Penso che cosi' possa funzionare. Pero' mi sembra al quanto macchinoso ed anche inutile dover ricreare tutta la struttura solo per gestire meglio lo xaml.

Che altre strategie potrei adottare?

 

 

sabrina_c has reacted to this post.
sabrina_c

Ciao Miky,

Quando è necessario creare una treeview di oggetti disomogenei, io creo una interfaccia a cui tutte le classi interessate devono rispondere, in modo che la collection che poi costruisce la tree sia fatta di interfacce non di classi e possa quindi contenere tutto quello che tu vuoi mettervi.

Per una normale tree l'interfaccia potrebbe contenere:

  • TipoNodo (da usare per mettere una icona che a colpo d'occhio ti dica cosa stai guardando)
  • ID (sperando che tutti gli ID siano dello stesso tipo e se così non fosse suggerisco una IDTree stringa in cui convertire con una property readonly tutti gli ID)
  • Descrizione x la tree (anche questa una property readonly composta con le info che vogliamo visualizzare per il nodo)

Ovviamente il tipo nodo serve anche per capire che cosa c'è nell'interfaccia e convertirlo nella classe giusta.
Può inoltre essere utilizzato per pilotare l'Editor da visualizzare per l'elemento corrente.

Solo per curiosità, quanti nodi ci sono nella tua tree? Perché fai attenzione che mettere oggettoni enormi in una tree potrebbe portare all'inchiodamento dell'interfaccia (lo dico x esperienza).

Spero di averti dato qualche idea.

Saluti

Grazie Sabrina, ottimo consiglio anche perchè di fatto uso questo stesso metodo per un altro progetto in cui trasformo dei json in "observable tree" e quindi so già bene come muovermi.

Questa volta, lavorando con poche tabelle sql, volevo evitare di creare oggetti o interfacce aggiuntive ma credo sia l'unica strada elegante e riciclabile per farlo.

Per ora non prevedo di dover gestire né molti nodi né nodi "grossi" ma se volessi, potrei gestire tutto il progetto in questo modo gerarchico, staremo a vedere.

Nell altro progetto, il framework per i json, mi sono scontrato anche io con il caricamento di dati pesanti ed avevo risolto in due modi: lavorando in asincrono ed evitando i controlli Syncfusion. Avevo fatto dei test con 30k documenti json e i controlli MS erano infinitamente piu' veloci di SF (testati datagrid e treegrid) inoltre SF non era in grado di lavorare correttamente in asincrono perche' lavorava sempre sul thread della gui. Avevo segnalato la cosa a SF ed effettivamente avevano riconosciuto il bug e rilasciato un fix. Non sono ancora riuscito a testarlo.

Altre due approcci che volevo introdurre erano il lazy load e il parallel.foreach ma non mi sono serviti.

Grazie ancora del suppporto

Non per fare pubblicità, ma c'è una nuova tree syncfusion fatta x tenere grandi quantità di nodi chenon ha i controlli farraginosi della vecchia Treeview ma può essere agganciata ai tuoi stessi oggetti, la sperimenterò fra poco, ed in caso vi do un feedback su come funziona con tanti dati.