Hej, Varför är det konstigt? du laddar ju om sidan klart att den då kör genom rutinerna igen :-) Det hade vart rätt osmart annars. Men varför kör du en redirect till samma sida? I subben som som sätter Session-värdet laddas inte kontrollen annars. Kontrollen laddas vid Page_Init, och Page_Init har redan körts när den kommer till subben som sätter Session-värdet. Redirectar jag, laddas kontrollen upp vid Page_Init nästa gång. Jonas, Du ser inget problem med att spara kontrollen i ett Sessionvärde då, som man sedan läser vid Page_Init? Man skulle kunna ladda kontrollen direkt i subben, och även spara ett sessionvärde där. När sedan sidan nästa gång initieras, laddas kontrollen in igen (ex vid postback). Jag skulle inte lagt den i en Session. För vad är vitsen? Om du lägger kontrollen på sidan och fyller den med data kommer denna att synas, vid en postback kommer den att fylla i datan igen (om du inte vill detta så har du alltiv viewstaten som minns vad du hade innan postback och behåller befintlig data åt dig.) Jag har en knapp som laddar UserControlen. Sedan i Page_Load på usercontrolen görs en koll om sidan är en postback, och om den inte är det, fylls kontrollen med default-data. Problemet blir då att sidan ÄR en postback, eftersom det är när man trycker på en knapp som kontrollen laddas. Jepp, Detta finns i Page_Init på sidan som håller kontrollerna: Jepp, det är din clear som ställer till det, detta event körs sist, och där rensar du kontrollerna som lagts till. Du måste då efter Add köra en DataBind rutin på den så den bygger upp sig igen. Det hjälpte inte. Vet inte om detta kan hjälpa dig men jag har löst det där med en aspx sida som alla undersidor ärver ifrån, och i denna aspx sida har jag följande kåd: Jonas, Rickard, Kul att lösningen kom till nytta :) Jag skulle vara lite försiktig med att lägga en massa data i viewstaten. (Bara en parantes i det hela) Vad skulle du föreslå? Kanske session istället? Jag tror att att du får väga för kontra emot, om du ska använda viewstate eller session. Alltså, värdena som lagras i Viewstaten är mycket små strängar, ex filsökvägar och flaggor.Dynamiska kontroller och postbacks?
Jag håller på att bygga en applikation som består av en .aspx-sida där kontroller (UserControls) laddas in dynamiskt - "at runtime".
Tidigare när jag har byggt sidor med sådan teknik har jag sparat vilken kontroll som ska laddas i ett sessionvärde och efter det redirectat tillbaka till samma sida där jag i Page_Init laddar kontrollen utifrån sessionvärdet, eftersom jag annars inte kunde få fram kontrollen efter postback.
Om man då följer hur sekvensen blir när man lägger till en kontroll i Debug, upptäcker man att sidan först postback'as och Page_Init gås igenom (laddar eventuellt upp gammal kontroll), sedan körs subben som sätter sessionvärdet, sidan laddas om genom Redirecten och kontrollen läses in via Page_Init och visas.
Ett ganska osmidigt flöde, enligt mitt tycke. Men det verkar omöjligt att få det smidigare, eftersom subben körs EFTER första Page_Init? Kanske om man laddar kontrollen direkt i subben? Hur skulle man då hantera postbacks? Risken är att två kontroller laddas då, och att det blir svårt att skilja på postback och när en ren kontroll ska laddas?
Någon som har något tips?Sv: Dynamiska kontroller och postbacks?
Mvh JohanSv:Dynamiska kontroller och postbacks?
Sv: Dynamiska kontroller och postbacks?
Du kan ju sätta den dynamiskt, och då kommer den att köra kontrollernas egna initiering m.m.
Så det skall inte vara några problem. Ev måste du kanske köra DataBinding på den som går genom alla controller.
Mvh JohanSv:Dynamiska kontroller och postbacks?
Rätt sätt att lösa det på?Sv: Dynamiska kontroller och postbacks?
Mvh JohanSv:Dynamiska kontroller och postbacks?
Om vi bortser från det felet, kommer detta "Det gick inte att ladda visningsläget. Kontrollträdet som visningsläget laddas till måste matcha kontrollträdet som användes för att spara visningsläget vid föregående begäran. Om kontroller till exempel läggs till dynamiskt måste kontrollerna som läggs till vid ett återanslående matcha typ och position för de kontroller som las till vid den ursprungliga begäran". Jag tömmer först kontrollerna som redan finns i kontrollutrymmet, innan jag laddar in nästa. Vilket som du ser skapar problem.
Detta är problem som jag måste över för vidare utveckling av applikationen, så jag är mycket tacksam för all hjälp.
Tack för ditt intresse hittills!Sv: Dynamiska kontroller och postbacks?
som det betyder så försöker du läsa in nått helt annat än vad som fanns vid en postback.
Ev går du till någon annan sida och där ha samma kontrol eller logik på nått sätt så sidan inte vill känna av viewstaten? är det så? eller är det den vanliga Postbacken som ger dig detta fel?
För lägger du till en kontroll dynamiskt så får den även en del av viewstatedatan, när en postback till samma sida sker så har du med denna viewstate som skall läsas in av kontrollerna, men aj pang något stämmer inte kontrollen eller nått finns inte eller stämmer inte och viewstaten vet inte vart den skall in och det blir bla detta fel.
Dock bör du inte få detta fel om du postar till samma sida och bygger upp samma kontrol som innan sidan postades om.
Kan du ge kod på just de saker som ger detta fel? lättare att se om du gjort nått annat som vi inte kan se just nu? kan vara små detaljer som ställer till det...
Mvh JohanSv:Dynamiska kontroller och postbacks?
Private Sub Page_Init(sender as Object, e as EventArgs)
If td_LeftPane.Controls.Count = 0 Then
td_LeftPane.Controls.Add(LoadControl("visakontroller.ascx"))
End If
End Sub
När jag sedan lägger till en kontroll, måste "visakontroller" bort:
Private Sub AddControl_Click(sender As Object, e As EventArgs) Handles AddControl.Click
td_LeftPane.Controls.Clear 'gissar att det är denna raden som ställer till det?
td_LeftPane.Controls.Add(LoadControl("enkontrollsommankundevaljaivisakontroller.ascx"))
End Sub
Allt är på samma sida.
Sv: Dynamiska kontroller och postbacks?
mvh JohanSv:Dynamiska kontroller och postbacks?
Felmeddelandet kommer efter det att kontrollen laddats upp, och sedan när jag gör en postback från den nya kontrollen.
Detta körs vid Page_Init på sidan som håller kontrollerna:
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
If Not UserAuthenticated Then
td_RightPane.Visible = False
td_LeftPane.Controls.Add(LoadControl("Parts/Login.ascx"))
Else
'Vänsterpanel
'------------
If td_LeftPane.Controls.Count = 0 Then
td_LeftPane.Controls.Add(LoadControl("Parts/ShowParts.ascx"))
End If
'------------
'Högerpanel
'------------
If td_LeftPane.Controls.Count = 0 Then
td_RightPane.Controls.Add(LoadControl("Parts/ShowParts.ascx"))
End If
'------------
lnk_Logout.Visible = True
lnk_SaveStart.Visible = True
End If
End Sub
Sedan i kontrollen ShowParts.ascx visas alla kontroller upp, och det är därifrån koden ur det tidigare inlägget kommer. Där väljer man alltså vilken kontroll man vill visa, och sedan laddas den upp i någon av panelerna. Därför får inte högerpanelen tappa data för att man laddar in en ny kontroll i vänsterpanelen, och vice versa. Helst ska sidan hela tiden hålla kvar data, och bara hantera kontroller utan att köra Response.Redirect någon gång alls.
Kanske kastar lite mer ljus över det hela? Bara skriv om något är oklart.
Tack så länge!
Sv: Dynamiska kontroller och postbacks?
<code>
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Put user code to initialize the page here
If Not IsPostBack Then
Else
If viewstate("LoadWUC") <> "" Then
'TODO: Ability to add more than just one WUC.
Me.AddWuc(Page.FindControl(viewstate("LoadWUC_CtrlOwnerID")), viewstate("LoadWUC"))
End If
End If
End Sub
Protected Friend Sub AddWuc(ByRef ParentControl As Control, ByVal sFilePath As String)
If Not ParentControl.FindControl(sFilePath) Is Nothing Then
'this wuc already exists, do not add anything.
Exit Sub
End If
Dim wuc As New UserControl
'Try
wuc = Page.LoadControl(sFilePath)
'Catch ex As Exception
' Exit Sub
' End Try
wuc = CType(wuc, UserControl) 'this conversion doesn't work. just gets ignored. why?
wuc.ID = sFilePath
ParentControl.Controls.Add(wuc)
viewstate("LoadWUC") = sFilePath
viewstate("LoadWUC_CtrlOwnerID") = ParentControl.ID
End Sub
Protected Friend Sub RemoveWucs(ByVal FromParentControl As Control)
'TODO: implement recursive removing of wuc's?
Dim c As Object
'this check might be done more optimal than this
For Each c In FromParentControl.Controls
Try
c = CType(c, UserControl)
'coming this far its a usercontrol, then remove it.
c.parent.controls.remove(c)
viewstate("LoadWUC") = ""
Catch ex As Exception
'not a usercontrol. do nothing.
End Try
Next
End Sub
</code>
Och sedan senare har jag en annan aspxsida som ärver från ovan, och implementerar lösningen såhär för att ta bort:
<code>
'remove usercontrols, clear colors and hide searchpanel.
Me.RemoveWucs(pnlContent)
</code>
Och såhär för att lägga till en kontroll:
<code>
AddWuc(pnlContent, PathToWUC & "wucSearchArt.ascx")
</code>
Lägger du till en kontroll kommer den återladdas varje gång tills du tömmer containern som innehåller kontrollen (med hjälp av viewstate)
Vad jag inte orkat göra än är möjligheten att ha flera userkontroller på flera ställen, men om du kollar på kåden kan du lätt skriva om den så att den klarar det. Arrays kanske?
Annars kan du ta en titt på ".NET Portal Starterkit" tror de har en liknande lösning implementerad, som baseras än bättre - på en logisk arkitektur i sql !
Hoppas det hjälper!
MVH RickardSv: Dynamiska kontroller och postbacks?
Aaa tror jag är med, är lite stressad och tog mig en snabb tankeställare inte säkert den riktiga.
Men vid en postback kan en ny kontroll laddas in om man exempelvis är godkänd?
Och innan visade du en helt annan kontrol så dess viewstate stämmer inte med den nya?
Antar att det är så du menar?
Om det är så har du som sagt lite problem :(
Dock kan du ju spara ner den data du måste ha från tidigare kontroll, och se till så viewstaten för kontrollen töms. Istället för att ta hela kontrollen i session kan du alltid skapa upp en class som du sätter dessa värden i som du i sin tur lägger i en session. Byggde en egen statehanterare dock hinner jag inte beskriva hur denna kan byggas just nu, kort bara.
Hade en singleton klass StateFactory denna i sig kan skapa en State som ger ett State objekt, alla Stateobjekt lades med en unik Key i en Hashtabel alla State objekt kan ha sina egna keys och values de med. Detta för att man kanske ha två states för två olika saker med flera olika värden / state.
StateFacortyn kunde även hämta in rätt stater med en key. State har en Save metod som i sin tur nyttjade en StateProvider som kunde gå mot Session eller databas eller XML, Load metod som använder denna Provider för att ladda in sig. På detta vis behöver jag inte bry mig vart staten sparas eller hur bara jag kan få tillbaka min state mellan kontrollbyten m.m.
Mvh JohanSv:Dynamiska kontroller och postbacks?
Jag har ett problem med din lösning: om jag vill ladda en kontroll innifrån en annan UserControl, hur går jag tillväga då? En UserControl kan inte ärva från .aspx-sidan...
Hur gör du för att avgöra om en UserControl är laddad för första gången eller inte?
Annars fungerar din lösning bra, Rickard. Jag använder den direkt på .aspx-sidan, och laddar upp kontrollerna där istället för i en UserControl, p.g.a. ovanstående problem.
Tack för hjälpen båda två (Jag förstod inte riktigt dig Johan, men jag märker att du är stressad nu, så jag försöker lösa det här ändå utan din hjälp).Sv: Dynamiska kontroller och postbacks?
Du kan även ha en MasterUserControl som alla andra ärver ifrån, istället för en MasterPage.
Då bör du kunna lägga till controller inom kontroller, men kom ihåg att du med denna
lösningen som den ser ut nu, inte kan ha flera kontroller laddade samtidigt, det måste du
lösa själv, kanske med en array eller något. Du kan ju pröva dock med att lägga till en webusercontrol
inuti en webusercontrol, kanske funkar?
"Hur gör du för att avgöra om en UserControl är laddad för första gången eller inte?"
Det kan du säkert lösa själv med en session eller viewstate variable, som du lägger till i samband med tillfället som AddWuc körs. Och sedan hämta den variabeln under page.postack.
Hoppas det hjälper!
Mvh RickardSv:Dynamiska kontroller och postbacks?
Några skäl du bör tänkte på.
1... Den tar plats på klinens minne
2... Den förs över vid post till server (vilket ger en hel del data i trafik till servern.)
3... Säkerhetskäl, viewstaten är inte skyddad om man inte skyddar den (tar dock mer tid för servern att hantera detta skydd.)
4... Viewstaten ligger alltid en sida efter. Alltså det du sparar i den för du tag i nästa sida.
Mvh JohanSv: Dynamiska kontroller och postbacks?
Har max sex variablar i viewstaten samtidigt som det är nu, och det kommer aldrig att bli fler än kanske 10 användare på sidan.
Säkerheten däremot, jag lagrar vilka UserControl som ska laddas i viewstaten. Man kan väl ändå inte ändra den till att ladda en UserControl som ligger utanför mitt webbhotell? Sen finns där säkerhetskoll som kontrollerar så att användaren är inloggad innan sidan som håller UserControlsen laddas. Så för att kunna utnyttja viewstateinformationen måste man ha en ny ASPX-sida som laddar kontroller via viewstaten utan att kolla om användaren är inloggad, och dessutom kunna lägga in nya UserControls eller länka till UserControls utanför webbhotellet.
Vad tror ni?Sv:Dynamiska kontroller och postbacks?
1 & 2:
Session kan vara att föredra absolut, men då belastas servern mer än klienten men man slipper
föra över data vilket kan ta lite tid om det är en stor viewstate. Använder man session
skapas en cookie på klienten som avgör vilket sessiondata tillhör just denna session (och klient).
Har man inte stöd för cookies kommer det inte funka dock .
I min lösning var det viktigt att just denna workload lades på klienten (alltså direkt i html som viewstate), och inte lät servern göra mer än att processa viewstate som skickades in.
(jobbade mot spec)
3: Sant kanske inte det säkraste dock är den krypterad och valideras, men kan nog brytas upp viewstate med lite trix. viewstate och säkerhet: <url>http://msdn.microsoft.com/msdnmag/issues/03/02/CuttingEdge/</url>
4: Sant, om du klickar på en annan sida kommer userkontrollinnehållet skickas med (dock inte renderas om du inte lägger till den på varje ny request)Sv: Dynamiska kontroller och postbacks?
Jag gjorde en liten optimisering på RemoveWUC eftersom den hanterade dem med Try/Catch-block, vilket jag inte tror är speciellt effektivt:
Private Sub RemoveUserControl(ByVal ctrlParent As Control)
Dim c As Object
For Each c In ctrlParent.Controls
If Left(c.GetType.FullName, 3) = "ASP" Then
c.parent.controls.remove(c)
'här kan viewstate eller session tömmas.
End If
Next
End Sub
Tack för den ursprungliga koden!