Persistenza di ListItemCollection in un controllo utente personalizzat...

lunedì 10 novembre 2008 - 18.03

ysdemarc Profilo | Expert

RISOLTO!!!... la soluzione in basso.

---------------------------
PROBLEMA
---------------------------
Ho visto che la ListItemCollection non è serializzabile e non viene salvata nella ViewState...

cercando su internet ho trovato quello che dovrebbe fare per me...

ecco il link: http://www.codenewsgroups.net/group/microsoft.public.dotnet.framework.aspnet.webcontrols/topic7569.aspx

però il codice non mi funziona.. da premettere che nel mio controllo personalizzato ho 2 "listbox"

e quindi ho cambiato i due metodi SaveViewState e LoadViewState in questo modo:
(ItemsForm rappresenta la prima ListitemCollection ItemsTo la seconda)

protected override object SaveViewState()
{
Pair pair = new Pair();
pair.First = base.SaveViewState();

Pair pair2 = new Pair();

if (itemsFrom != null) pair2.First = ((IStateManager)itemsFrom).SaveViewState();
if (itemsTo != null) pair2.Second = ((IStateManager)itemsTo).SaveViewState();

pair.Second = pair2;

return pair;
}

protected override void LoadViewState(object savedState)
{
Pair pair = (Pair)savedState;

if (pair != null)
{
if (pair.Second != null && pair.Second.GetType()==typeof(Pair))
{
Pair pair2 = (Pair)pair.Second;

if (itemsFrom == null) itemsFrom = new ListItemCollection(); // queste si sono rese necessari in quando mi sono accorto che andanto a fare le rispettive LoadViewState andava in NullReferenceException
if (itemsTo == null) itemsTo = new ListItemCollection();

if (pair2.First != null)
{
((IStateManager)itemsFrom).LoadViewState(pair2.First);
}
else
{
((IStateManager)itemsFrom).TrackViewState(); // questa invece poichè ho notato che se non viene usato il metodo add di uno dei 2 collection alla fine sembrava non salvare lo stato del controllo..
//nota 1
}
if (pair2.Second != null)
{
((IStateManager)itemsTo).LoadViewState(pair2.Second);
}
else
{
((IStateManager)itemsTo).TrackViewState();
//nota 1
}
}

base.LoadViewState(pair.First);
}

}

Alla fine di tutto questo non funziona niente..

o meglio il primo caricamente della pagina va bene..
caricando la pagina ho solo la prima collection valorizzata.. dal controllo
il controllo non dovrebbe fare altro che spostare con script client gli elementi dal primo al secondo.

quindi facendo una banale postback senza spostare alcun elemento, continua a funzionare, appena sposto un solo elemento dalla prima lista alla secondo e faccio il postback mi accorgo che il programma entra nell'else delle if che ho contrassegnato come //nota 1

Qualcuno saprebbe aiutarmi..sinceramente il codice l'ho copiato bovinamente senza riuscire a capire il funzionamento..
e soprattutto come posso risolverlo?
Ho provato a usare la Session per memorizzare i dati, ma alla lettura gli items non mi cambiano se non dopo il secondo postback poichè se un pulsate tipo submit fa il postback, prima scatena l'evento page_load, poi va nel submit e poi elabora i controlli e quindi cambierebbe le session..per cui sarebbero necessatrie 2 postback consecutive per avere quello che volgio in questo caso...

ma rpeferirei una sintassi ed una logica più pulita..

sono fermo da settimane su sto controllo..aiutoooo
Vincenzo
Programmatore sbilenco

----------------------------------------------------
MI RISPONDO DA SOLO: RISOLTO!!!!!
----------------------------------------------------
magari a qualcuno che si troverà in una sistuazione simile la cosa potrà interessare..
ecco la soluzione:

//dichiarazione delle variabili
private ListItemCollection itemsFrom;
private ListItemCollection itemsTo;

//proprietà del controllo
[Bindable(true),
Category("Data"),
DefaultValue(""),
Description("Ottiene l'insieme degli elementi della lista 1.")]
[Editor("System.Web.UI.Design.WebControls.ListItemsCollectionEditor,System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
typeof(System.Drawing.Design.UITypeEditor))]
[MergableProperty(false)]
public ListItemCollection ItemsFrom
{
get
{
if (itemsFrom == null)
{
itemsFrom = new ListItemCollection();
}
return itemsFrom;
}
}
[Bindable(true),
Category("Data"),
DefaultValue(""),
Description("Ottiene l'insieme degli elementi della lista 2.")]
[Editor("System.Web.UI.Design.WebControls.ListItemsCollectionEditor,System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(System.Drawing.Design.UITypeEditor))]
[MergableProperty(false)]
public ListItemCollection ItemsTo
{
get
{
if (itemsTo == null)
{
itemsTo = new ListItemCollection();
}
return itemsTo;
}
}

//E adesso li mettiamo in ViewState

protected override void LoadViewState(object savedState)
{
if (savedState != null)
{
object[] myState = (object[])savedState;

if (myState[0] != null)
base.LoadViewState(myState[0]);

if (myState[1] != null)
((IStateManager)itemsFrom).LoadViewState(myState[1]);

if (myState[2] != null)
((IStateManager)itemsTo).LoadViewState(myState[2]);

Inizializzazioni(); //qui faccio le mie operazioni con le quali aggiungo o tolgo elementi ai ListItemCollection inoltre qui ho anche la Request..
}

}

protected override object SaveViewState()
{
object[] allStates = new object[3];

allStates[0] = base.SaveViewState();

allStates[1] = ((IStateManager)itemsFrom).SaveViewState();
allStates[2] = ((IStateManager)itemsTo).SaveViewState();

return allStates;
}

protected override void TrackViewState() //questo era quello che mi mancava e per cui perdevo al secondo postback i dati
{
base.TrackViewState ();

if (itemsFrom == null) itemsFrom = new ListItemCollection();
if (itemsTo == null) itemsTo = new ListItemCollection();

((IStateManager)itemsFrom).TrackViewState();
((IStateManager)itemsTo).TrackViewState();
}

che faticata.... magari a qualcuno sarà sembrato banale..ma con la poca infarinatura sonoarrivato qui dopo giorni di prove...
mi ringrazio da solo ...

anzi no ringrazio questo articolo che mi ha dato l'illuminazione: http://aspnet.html.it/articoli/leggi/2327/datasource-personalizzati/6/

ciaooooooooooooo
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-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5