Lista di userControl

lunedì 19 marzo 2012 - 11.53
Tag Elenco Tags  C#  |  .NET 2.0  |  .NET 4.0  |  Visual Studio 2010  |  Visual Studio 2008

skibu Profilo | Junior Member

Ciao a tutti, ho la necessità di visualizzare un elenco di user controll (caricati in modo dinamico) in una form.
Ho creato il mio componente, una textbox e un'immagine, però non so come creare una lista che contenga questi componenti.
Dovrei caricare questi componenti, uno per ogni record che recupero da una tabella, per ognuno caricare il valore di un campo nella textbox e un'immagine.
Esiste un modo per farlo?

u235 Profilo | Junior Member

>Ciao a tutti, ho la necessità di visualizzare un elenco di user
>controll (caricati in modo dinamico) in una form.
>Ho creato il mio componente, una textbox e un'immagine, però
>non so come creare una lista che contenga questi componenti.
>Dovrei caricare questi componenti, uno per ogni record che recupero
>da una tabella, per ognuno caricare il valore di un campo nella
>textbox e un'immagine.
>Esiste un modo per farlo?

ciao, di modi potresti usarne tanti, uno può essere quello di creare una lista tramite reflection :
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra


e quando selezioni dalla listBox (o comunque, quando vuoi creare l'istanza) :

[CODE] var userControl = types[i].Assembly.CreateInstance(types[i].FullName); [/CODE]

oppure bisogna capire cosa recuperi dal database, il nome della classe? i parametri? oppure per ogni record carichi più istanze dello stesso userControl? spiegati meglio, magari postando ciò che hai fatto.

skibu Profilo | Junior Member

io dal database recupero una descrizione e il percorso dell'immagine, così da visualizzarli in un usercontroll.
Vorrei che questo caricamento fosse dinamico, cioè avere una lista di miei componenti, per ogni record visualizzare un usercontrol istanziato.
esiste un modo? utilizzando una listbox?

in un'applicazione web userei una datagridview con una colonna di tipo itemptemplate, ma in una applicazione winform?

u235 Profilo | Junior Member

>io dal database recupero una descrizione e il percorso dell'immagine,
>così da visualizzarli in un usercontroll.
>Vorrei che questo caricamento fosse dinamico, cioè avere una
>lista di miei componenti, per ogni record visualizzare un usercontrol
>istanziato.

una volta creata l'istanza la valorizzi come un qualsiasi componente, non cambia se l'hai creato dinamicamente. a tal proposito ti consiglio di far implementare un tipo Interface ai tuoi userControl in modo da poter valorizzare senza troppi giri i tuoi campi.
esempio:

[CODE] public interface IMioControllo { string Testo { get; set; } } public partial class UserControl1 : UserControl, IMioControllo { public UserControl1() { InitializeComponent(); } public string Testo { get { return this.textBox1.Text; } set { textBox1.Text = value; } } } public partial class UserControl2 : UserControl, IMioControllo { public UserControl2() { InitializeComponent(); } public string Testo { get { return this.textBox1.Text; } set { textBox1.Text = value; } } } [/CODE]

e la lista la puoi creare così :

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra


oppure puoi usare i dynamic (se usi il framework 4.0) senza interface, ma in questo caso devi accertarti che tutti i tuoi UserControl abbiamo (come per questo esempio) una proprietà Testo.

esempio:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra


negli esempi sopra, prima creo una lista di istanze di userControl, 1 per ogni tipo che deriva da UserControl nel caso senza interface, oppure 1 per ogni tipo che implementa l'interface (solo quelle e teoricamente potrebbe non essere un UserControl ma un qualsiasi derivato da Control), poi imposto il testo nella proprietà Testo e lo aggiungo ad un contenitore (in questo caso panel). Ovviamente per prendere i valori da db non dovrebbe essere difficile.

comunque io ti consiglio a limite di usare una lista di tipi dalla quale poi peschi il controllo che ti serve e ne crei l'istanza, o meglio ancora, chiami il tipo che ti serve quando ti serve e lo crei (magari quando estrai i dati) senza fare una lista prima.

>esiste un modo? utilizzando una listbox?
>

si :) più di uno! ma la listBox non ha nulla a che vedere se non per visualizzare!

>in un'applicazione web userei una datagridview con una colonna
>di tipo itemptemplate, ma in una applicazione winform?

tieni presente che WinForm non è web...
probabilmente stai sbagliando approccio, prova a dettagliare bene cosa vuoi fare, probabilmente si risolve con un datagridview o comunque in qualche altro modo. Molto raramente in winForm si aggiungono gli userControl dinamicamente prendendo dati da db. Nel particolare, mi sembra più corretto (visto che devi usare textBox e image) usare un DataGridView con le colonne corrette (oltretutto puoi creartele personalizzate). Se poi vuoi "avvicinarti" di più al modo "web", allora scegli WPF e non windows form, li usi magnificamente i template e fai esattamente quello che vuoi con molto meno sforzo di windows form.

skibu Profilo | Junior Member

grazie per i suggerimenti.

recupero dal db diverse descrizioni e relativo percorso dell'immagine, l'utente deve avere la possibilità di visualizzare tutti questi elementi e sceglierne uno (pensavo con un radio button in ogni elemento). Il risultato che vorrei ottenere l'ho allegato con un'immagine.


527x223 20Kb


la logica con cui pensavo di procedere era:
-recupero i dati dal db
-per ogni record istanzio un oggetto mio control user, impostando descrizione, immagine
-aggiungo questo oggetto ad una lista o a un contenitore per visualizzarlo


u235 Profilo | Junior Member

>grazie per i suggerimenti.
>
Figurati :)

>recupero dal db diverse descrizioni e relativo percorso dell'immagine,
>l'utente deve avere la possibilità di visualizzare tutti questi
>elementi e sceglierne uno (pensavo con un radio button in ogni
>elemento). Il risultato che vorrei ottenere l'ho allegato con
>un'immagine.
>
>
>
>la logica con cui pensavo di procedere era:
>-recupero i dati dal db
>-per ogni record istanzio un oggetto mio control user, impostando
>descrizione, immagine
>-aggiungo questo oggetto ad una lista o a un contenitore per
>visualizzarlo
>
>
>
comunque avevo capito male prima :) pensavo volessi altro...
se lavori in wpf ti basterebbe crearti il tuo itemTemplate con gli elementi che ti servono (tipo image, text ecc.) per generare gli insiemi, poi metti come ItemsPanelTemplate un WrapPanel per fare in modo che gli elementi siano posti in maniera "consecutiva" fino alla fine della "riga", e poi vadano direttamente a capo (anche quando si ridimensiona il controllo), il resto lo fa il binding sull'ItemSouce (ti crea gli elementi), non devi fare nessun ciclo, ti basta bindare le proprietà dei tuoi dati nel ItemTemplate, l'immagine con il percorso del BD tramite converter, la descrizione con il campo corretto ecc.
A limite ti posso postare un esempio, non l'ho fatto ora perchè non so se vuoi WPF (oltre a non sapere se magari sei già in WPF!)

skibu Profilo | Junior Member

>comunque avevo capito male prima :) pensavo volessi altro...
>se lavori in wpf ti basterebbe crearti il tuo itemTemplate con
>gli elementi che ti servono (tipo image, text ecc.) per generare
>gli insiemi, poi metti come ItemsPanelTemplate un WrapPanel per
>fare in modo che gli elementi siano posti in maniera "consecutiva"
>fino alla fine della "riga", e poi vadano direttamente a capo
>(anche quando si ridimensiona il controllo), il resto lo fa il
>binding sull'ItemSouce (ti crea gli elementi), non devi fare
>nessun ciclo, ti basta bindare le proprietà dei tuoi dati nel
>ItemTemplate, l'immagine con il percorso del BD tramite converter,
>la descrizione con il campo corretto ecc.
>A limite ti posso postare un esempio, non l'ho fatto ora perchè
>non so se vuoi WPF (oltre a non sapere se magari sei già in WPF!)
>
>

un esempio mi sarebbe di grande aiuto! non sto usando wpf, ma se dici che è più semplice o immediato mi sposto su quello altrimenti devo trovare un modo per farlo con un'applicazione winform.
grazie ancora!

u235 Profilo | Junior Member

MainWindow.xaml
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra


MainWindow.xaml.cs
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra


Ciao.

skibu Profilo | Junior Member

ciao, ho fatto un pò di prove..però non so se è la soluzione migliore usare wpf non per il fatto dello user control che devo creare ma perchè il programma è molto articolato, serve per diverse procedure e con winform faccio tutto alla perfezione.
ti chiedo, se dovessi realizzarlo con winform cosa useresti?

u235 Profilo | Junior Member

Ciao, per ottenere qualcosa che si avvicina a quello che vuoi tu userei probabilmente un listview oppure un datagridview ma con celle personalizzate, oppure farei a mano il tutto (come ho capito che volevi fare tu) da codice aggiungendo uc ad un contenitore, anche se personalmente non gradisco "più" questa soluzione, che comunque a mio parere ti costringe a "lavorare" un pò di più e ad avere il codice meno pulito e meno versatile, e poi ormai penso che stia diventando un pò "FanBoy" (si fa per dire, il mio è un confronto tra tecnologie che conosco) di XAML :) un pò per la versatilità nella grafica, un pò per il magnifico supporto al binding, un pò per la possibilità di portare le interfaccie da desktop a web con semplicità, un pò... per tanti altri motivi!

Comunque, per quanto riguarda le altre procedure, nulla ti vieta di portarle in wpf senza troppe modifiche, ovviamente dipende se non le hai mischiate troppo con l'interfaccia grafica, ma se così fosse, ricordati che WPF e Windows Form posso essere mischiate nello stesso progetto, anche se è una cosa che eviterei sempre per questioni di "pulizia", ma nulla te lo vieta.

skibu Profilo | Junior Member

il mio problema è proprio quello di aggiungerli ad un contenitore, come creo una lista di questi oggetti?
con la datagridview è possibile inserire un'immagine, una textbox nella stessa cella? o si riescono ad aggiungere i miei uc direttamente come source?

u235 Profilo | Junior Member

>il mio problema è proprio quello di aggiungerli ad un contenitore,
>come creo una lista di questi oggetti?

la lista la crei con una semplice List<> e aggiungi i controlli ad essa. Volendo puoi usare il tipo UserControl (List<UserControl) oppure i control (List<Control>) oppure specificare un'interfaccia che implementa i membri che ti servono su tutti come ti ho mostrato nell'altro post (List<IMioControllo>) o con dynamic (List<dynamic>). insomma ci sono talmente tanti modi di creare una lista... Io fossi in te mi preoccuperei piuttosto della gestione della disposizione dei controlli, ma nemmeno più di tanto, solo che non viene una cosa molto pulita... ma forse la cosa non ti interessa :)
comunque per capirci meglio basta che fai :

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra


>con la datagridview è possibile inserire un'immagine, una textbox
>nella stessa cella? o si riescono ad aggiungere i miei uc direttamente
>come source?

è un pò più complesso di wpf fare questo con il datagridview di windows form. Dovresti crearti una cella personalizzata ereditando da DataGridViewCell ed impostando la tua classe derivata nella colonna, ma probabilmente avrai bisogno di creare anche la colonna personalizzata per poter impostare i dati nella cella(visto che sono più campi) , e a sua volta probabilmente sarai costretto a creare anche il controllo editor per la cella.

skibu Profilo | Junior Member

>>il mio problema è proprio quello di aggiungerli ad un contenitore,
>>come creo una lista di questi oggetti?
>
>la lista la crei con una semplice List<> e aggiungi i controlli
>ad essa. Volendo puoi usare il tipo UserControl (List<UserControl)
>oppure i control (List<Control>) oppure specificare un'interfaccia
>che implementa i membri che ti servono su tutti come ti ho mostrato
>nell'altro post (List<IMioControllo>) o con dynamic (List<dynamic>).
>insomma ci sono talmente tanti modi di creare una lista... Io
>fossi in te mi preoccuperei piuttosto della gestione della disposizione
>dei controlli, ma nemmeno più di tanto, solo che non viene una
>cosa molto pulita... ma forse la cosa non ti interessa :)
>comunque per capirci meglio basta che fai :
>
>[CODE] >List<UserControl> listaUserControl = new List<UserControl>();//lista >dichiarata come campo della classe > //ciclo >UserControl1 mioUserControl = new UserControl1(); >//qui imposto le proprietà del controllo compreso la posizione > >//poi aggiungo alla lista, ma tieni presente che hai gia una >lista di controlli (this.panel1.Controls) che puoi recuperare >quando vuoi >//quindi non sarebbe neppure necessario creare "listaUserControl" >ed aggiungere il controllo anche ad essa, >//ma visto che la tua richiesta è proprio questa... > listaUserControl.Add(mioUserControl); > > //e lo aggiungo al contenitore > this.panel1.Controls.Add(mioUserControl); > //fine ciclo >[/CODE]
>

questo mi va bene!
si l'unica cosa che rimane è la disposizione degli elementi, in modo che siano ordinati
l'unica soluzione che mi viene in mente in questo momento è quella di impostare la location "calcolata", in modo da avere la stessa spaziatura tra uno e l'altro e di visualizzarli per esempio in righe da 4. O secondo te c'è un altro modo?

u235 Profilo | Junior Member

>questo mi va bene!
>si l'unica cosa che rimane è la disposizione degli elementi,
>in modo che siano ordinati
>l'unica soluzione che mi viene in mente in questo momento è quella
>di impostare la location "calcolata", in modo da avere la stessa
>spaziatura tra uno e l'altro e di visualizzarli per esempio in
>righe da 4. O secondo te c'è un altro modo?
>

adesso è da un pò che non progetto su win form, oltretutto come già detto, non mi è mai capitato una cosa simile, o meglio, quando è capitato ho preferito fare con il datagridview derivando celle e colonne.
comunque potresti sfruttare un tablelayoutpanel e/o fai un ciclo annidato che determina righe e colonne (quindi posizioni dei controlli) in base al numero di elementi.

skibu Profilo | Junior Member


>
>adesso è da un pò che non progetto su win form, oltretutto come
>già detto, non mi è mai capitato una cosa simile, o meglio, quando
>è capitato ho preferito fare con il datagridview derivando celle
>e colonne.
>comunque potresti sfruttare un tablelayoutpanel e/o fai un ciclo
>annidato che determina righe e colonne (quindi posizioni dei
>controlli) in base al numero di elementi.

ok mi va benissimo :)

grazie per tutto l'aiuto che mi hai dato!
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2017
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5