Avatar billede kennedk Nybegynder
20. oktober 2007 - 13:24 Der er 41 kommentarer og
1 løsning

undgå postback for at opdatere updatepanel

Hej eksperter.
Jeg sidder og har en side med et updatepanel i, som sidens indhold skal være på.
Og sidens indhold er i UserControls, som bruger lagt ind i mit updatepanel med et multiview. sådan her:


<asp:UpdatePanel ID="upIndhold" runat="server" UpdateMode="Conditional" >
        <ContentTemplate>
            <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
            <asp:MultiView ID="MultiUserControl" runat="server" ActiveViewIndex="0">
            <asp:View ID="MultiUserControlBeskyttet" runat="server">
                <uc:Beskyttet ID="ucBeskyttet" runat="server" />
            </asp:View>
            <asp:View ID="MultiUserControlDefault" runat="server">
                <uc:Default ID="ucDefault" runat="server" />
            </asp:View>
            <asp:View ID="MultiUserControlRedigerSide" runat="server">
                <uc:RedigerSide ID="ucRedigerSide" runat="server" />
            </asp:View>
            </asp:MultiView>
            <asp:HiddenField ID="HiddenFieldToUpdateIndhold" runat="server" Value="Default.ascx;0" />
        </ContentTemplate>
</asp:UpdatePanel>

Som i kan se er der også et hiddenfield, som jeg burger til at opdatere mit updatepanel med, og den værdi det hidden field har finder ud af hvilket usercontrol der skal vises.

jeg opdatere updatepanelet med javascript sådan her:


function postBackIndhold(side,id) {
    var hiddenField = $get("<%=HiddenFieldToUpdateIndhold.ClientID %>");
    if (hiddenField) {
        hiddenField.value = side + ";" + id;
        __doPostBack("<%=HiddenFieldToUpdateIndhold.ClientID %>",'');
    }
}

men der giver mig et problem, når jeg vil bruge en textbox inde på  sidens indhold, altså i et userControl.
jeg kan jo ikke tjekke om det er IsPostBack, for det er det jo hele tiden da jeg opdatere det ved postback.

så denne kode :

public partial class WebUserControls_RedigerSide : System.Web.UI.UserControl
{
    protected void Page_Load(object sender, EventArgs e)
    {
        propSide propSide = facSide.GetSide(Convert.ToInt32(Session["SideID"]));
        if (propSide != null)
        {
            txtHeadline.Text = propSide.Navn;
            txtText.Text = propSide.Tekst;
        }

    }

    protected void btnOK_Click(object sender, EventArgs e)
    {
        lblError.Visible = true;
        lblError.Text = txtHeadline.Text;
    }
}

her når man trykker på knappen vil man altid så skrevet det ud der står i databasen, og ikke det der indtastet, da det bliver overskrevet..

Hvordan finder man en løsning på det?
Avatar billede dr_chaos Nybegynder
20. oktober 2007 - 20:03 #1
Prøv evt med Page.IsCallback
Avatar billede kennedk Nybegynder
20. oktober 2007 - 22:37 #2
Jeg har sat koden ind i mit Page_Load
if (Page.IsCallback)
        {
            lblError.Text = "Callback";
        }
        else
        {
            lblError.Text = "NOTCallback";
        }

og den udskriver NOTCallback hele tiden, uanset om jeg klikker på knappen inde i mit usercontrol
Avatar billede dr_chaos Nybegynder
20. oktober 2007 - 22:56 #3
ok så er det ikke løsningen.
Henter linien:
propSide propSide = facSide.GetSide(Convert.ToInt32(Session["SideID"]));
Text fra databasen ?
Avatar billede kennedk Nybegynder
20. oktober 2007 - 23:00 #4
ja, det er en funktion der retunere en property med database værdierne i :)
Avatar billede dr_chaos Nybegynder
20. oktober 2007 - 23:10 #5
Ja men dermed vil den også overskrive tekst værdierne ved hvert postback og derfor får du aldrig dine indtastede værdier.
prøv med

propSide propSide = facSide.GetSide(Convert.ToInt32(Session["SideID"]));
        if (propSide != null && !Page.IsPostBack)
        {
            txtHeadline.Text = propSide.Navn;
            txtText.Text = propSide.Tekst;
        }
Avatar billede kennedk Nybegynder
20. oktober 2007 - 23:14 #6
Nu bliver den jo ikke loadet da den altid er et postback, da jeg opdatere mit updatepanel med et postback..

hm,
Er der andre måder man kan opdatere det på via javascript, så man undgår at det er postback hele tiden?
Avatar billede dr_chaos Nybegynder
20. oktober 2007 - 23:18 #7
Måske kan du lave en public function som kan returnerer textbox værdien for dig Kombineret med en som du kan kalde for at hente tekst værdier fra databasen.
Avatar billede kennedk Nybegynder
20. oktober 2007 - 23:20 #8
Hm. Hvis det nu var dig, hvordan vil du så løse problemet? jeg er åben for nye ideer :)
Avatar billede neoman Novice
20. oktober 2007 - 23:28 #10
Og i den sidste artikel er der et andet fif i indlæggene:
"Hi. I was waving some trouble precisely with initialisation of web user controls. I then was told you can use Page_Init , and it works. code in Page_Init fires only once at initialisation for controls, so it's the equivalent of doing Page_Load and then checking for IsPostBack == true"
Avatar billede kennedk Nybegynder
20. oktober 2007 - 23:34 #11
hm tjae, det forstod jeg så ikke ret meget af . :) kan jeg få en lille forklaring?
Avatar billede neoman Novice
20. oktober 2007 - 23:39 #12
af hvad ??
Avatar billede neoman Novice
20. oktober 2007 - 23:41 #13
jeg mener er det en af artiklerne du ikke forstod eller mit sidste indlæg ?
Avatar billede kennedk Nybegynder
20. oktober 2007 - 23:41 #14
altså nu har jeg prøvet at bruge Page_Init i stedet for Page_Load og det virker ikke, så  udskrives dataen den første gang, og så udskrives den ikke mere. og det må så være fordi den kun læser koden een gang.

Og det andet kode der var vist, det forstod jeg ikke hvordan det skulle sættes ind.
Avatar billede neoman Novice
20. oktober 2007 - 23:56 #15
jeg har læst lidt mere på Init - og meningerne er lidt delte om man kan bruge den som på denne måde.

Men det som står i
http://blogs.clearscreen.com/enadan/archive/2006/02/21/2838.aspx
kan man stjæle lidt fra: simpelthen gemme kontrollens status i viewstate.

Nu er jeg bedre til VB end C# så i Vb ville det se sådan ud:

Dim reloaded as Book = False
If Not IsNull(ViewState("mitKontrolNavn") Then
    reloaded=CType(ViewState("mitKontrolNavn"), Boolean)
EndIF

    If Not Reloaded Then
      reloaded = true
    end If
    ViewState("mitKontrolNavn")=reloaded

også har du dit check:

If NOt reloaded Then
    ' så er den ved at blive loaded første gang
else
    ' så har den været loaded på denne side før
End If
Avatar billede neoman Novice
20. oktober 2007 - 23:56 #16
Dim reloaded as Boolean = False skulle der stå
Avatar billede neoman Novice
20. oktober 2007 - 23:57 #17
og alt dette skulle du klistre ind i din usercontrol:)
Avatar billede neoman Novice
21. oktober 2007 - 00:05 #18
Dim reloaded as Book = False
If Not IsNull(ViewState("mitKontrolNavn") Then
    reloaded=CType(ViewState("mitKontrolNavn"), Boolean)
EndIF


også har du dit check:

If NOt reloaded Then
    ' så er den ved at blive loaded første gang
else
    ' så har den været loaded på denne side før
End If


    If Not Reloaded Then
      reloaded = true
    end If
    ViewState("mitKontrolNavn")=reloaded

det skal naturligvis være i denne rækkefølge, ellers sker der ikke ret meget)
Avatar billede kennedk Nybegynder
21. oktober 2007 - 00:12 #19
Boolean reloaded = false;
        if (ViewState["mitKontrolnavn"] != null)
        {
            reloaded = Convert.ToBoolean(ViewState["mitKontrolnavn"]);
        }       
        if (reloaded)
        {
          lblError.Text = "Callback";
        }
        else
        {
          lblError.Text = "NOTCallback";
        }
        if (!reloaded)
        {
            reloaded = true;
        }
        ViewState["mitKontrolnavn"] = reloaded;

Denne kode udskriver callback hele tiden :/
Avatar billede kennedk Nybegynder
21. oktober 2007 - 00:15 #20
jeg prøver lige at hive siden på nettet så i kan se hvad jeg mener med det:)
Avatar billede neoman Novice
21. oktober 2007 - 00:20 #21
jeg grubler lidt, for kan ikke se fejl i koden.. endnu da:) Hvor har du lagt koden ind - i PageLoad på din usercontrol , ikke ?
Avatar billede kennedk Nybegynder
21. oktober 2007 - 00:21 #22
jo, det har jeg :)
Jeg brokker lidt med min database med at uploade den, det tager lige et minut endnu :)
Avatar billede neoman Novice
21. oktober 2007 - 00:23 #23
Kan det tænkes at din usercontrol bliver loaded to gange ? Prøv at sætte et breakpoint inde i den , så kan du se om det sker to gange.
Avatar billede kennedk Nybegynder
21. oktober 2007 - 00:25 #24
Hvordan breakpoint?

http://cms.webint.dk/cms
brugernavn er kenneth og koden er kenneth

så kan du se hvordan den er bygget op.
Forside, 1Testside, 2Testside, underside, inaktiv hjemmeside, 404 fejl og sitemap bruger den samme usercontrol.
Avatar billede neoman Novice
21. oktober 2007 - 00:28 #25
Yeah - men jag kan ikke udfra se om den bliver loaded to gange. I den venstre yderkant af kodevinduet  - den grå vertikale bjælke i koden på din user control -  klik med musen - der vil komme en rød klat som er et break point. Når du nu trykker på Kør (den grønne pil), så vil koden stoppe der. Tryk på den grønne pil igen, og fortæl om koden stopper en gang til eller ej:)

For at blive af med klatten senere tryk blot på den igen.
Avatar billede kennedk Nybegynder
21. oktober 2007 - 00:34 #26
Den kommer kun ned i debugging 1 gang.

Her er koden der loader kontrollet.
Det er lidt kringlet da det bare lige skulle virke hurtigt

    private void LoadIndhold(string userContol)
    {
        // til tjek af rettigheder, om brugeren må loade usercontrollen

        string[] userControls = new string[2];
        userControls[0] = "Default.ascx;Administrator";
        userControls[1] = "RedigerSide.ascx;SideEdit";

        Boolean boolPermission = false;
        string userControlURL = userContol;
        for (int i = 0; i < userControls.Length; i++)
        {
            string[] userControlsTjek = userControls[i].Split(';');
            if (userControlsTjek[0] == userControlURL)
            {
                boolPermission = CMS.Users.User.hasPermission(userControlsTjek[1], User.UserId);
                break;
            }
        }
        if (!boolPermission)
        {
            userContol = "Beskyttet.ascx";
        }

        if (!string.IsNullOrEmpty(userContol))
        {
            if (userContol == "Beskyttet.ascx")
            {
                MultiUserControl.ActiveViewIndex = 0;
            }
            if (userContol == "Default.ascx")
            {
                MultiUserControl.ActiveViewIndex = 1;
            }
            if (userContol == "RedigerSide.ascx")
            {
                if (Convert.ToInt32(Session["SideID"]) == Convert.ToInt32(Session["AktivID"]))
                {
                    Session["AktivID"] = 0;
                }
                    MultiUserControl.ActiveViewIndex = 2;
            }
        }
    }


og min usercontrol ser såan her ud
using System;
using CMS.SideEdit;
using System.Web.UI.WebControls;

public partial class WebUserControls_RedigerSide : CMS.Web.CodeBaseUserControl
{
    protected void Page_Load(object sender, EventArgs e)
    {
        lblError.Visible = true;
        Boolean reloaded = false;
        if (ViewState["mitKontrolnavn"] != null)
        {
            reloaded = Convert.ToBoolean(ViewState["mitKontrolnavn"]);
        }       
        if (reloaded)
        {
          lblError.Text = "Callback";
        }
        else
        {
          lblError.Text = "NOTCallback";
        }
        if (!reloaded)
        {
            reloaded = true;
        }
        ViewState["mitKontrolnavn"] = reloaded;

        propSide propSide = facSide.GetSide(Convert.ToInt32(Session["SideID"]));
        if (propSide != null)
        {
            txtHeadline.Text = propSide.Navn;
            txtText.Text = propSide.Tekst;
        }

    }
}

Hvis det kan give en bedre ide?
Avatar billede neoman Novice
21. oktober 2007 - 00:37 #27
fatter nada - og det ER "Callback" den skriver ? Ikke "NOTCallback" ?
Avatar billede kennedk Nybegynder
21. oktober 2007 - 00:40 #28
Du kan gå ind på siden og kigge :) Det er en kopi.
Det står lige under knappen gem ændringer .
Avatar billede neoman Novice
21. oktober 2007 - 00:41 #29
Og der er ingen andre kontroller som skriver noget i lblError.Text ?
Avatar billede kennedk Nybegynder
21. oktober 2007 - 00:42 #30
Nej, du har fået koden fra mit userkrontrol :)
kan det være noget med den if sætning der tjekker om viewstaten er null ? ved ikke hvordan man skal tjekke om viewstate et sat.
Avatar billede neoman Novice
21. oktober 2007 - 00:53 #31
Det er den måde man chekcer det på vist - i vb skal man skrive (skrev fejl før)

IsNothing (ViewState("blabla"))  men tror du godt kan checke på null i C# sådan som du gør.

Men sagen er at den kommer ind i den If block, fordi reloaded=true, og det er den eneste måde det kunne sættes på - derfor fatter jeg intet, og mistænkte at kontrollen blev også loaded flere end een gang.

I øvrigt, hele idéen duer ikke i den nuværende form, fordi du genbruger kontrollen på en del sider, mensom faktisk alle er den samme aspx side. Og det vil sige når ViewState for kontrollen een gang er sat, så bliver den ved med at være sådan,når du kalder kontrollen et andet sted fra (fordi det er samme page). MEn dat kan man sikkert  fikse.
Avatar billede neoman Novice
21. oktober 2007 - 00:55 #32
Det er vel ikke sådan at der er andre usercntroller som nedarver fra den du skrev her og som også bliver loaded ?
Avatar billede kennedk Nybegynder
21. oktober 2007 - 00:59 #33
nej, det med at den nedarver fra en anden klasse har ingen betydning, da der ikke sker noget i den klasse, så koden kunne lige så godt være.

using System;
using CMS.SideEdit;
using System.Web.UI.WebControls;

public partial class WebUserControls_RedigerSide : System.Web.UI.UserControl
{
    protected void Page_Load(object sender, EventArgs e)
    {
        lblError.Visible = true;
        Boolean reloaded = false;
        if (ViewState["mitKontrolnavn"] != null)
        {
            reloaded = Convert.ToBoolean(ViewState["mitKontrolnavn"]);
        }       
        if (reloaded)
        {
          lblError.Text = "Callback";
        }
        else
        {
          lblError.Text = "NOTCallback";
        }
        if (!reloaded)
        {
            reloaded = true;
        }
        ViewState["mitKontrolnavn"] = reloaded;

        propSide propSide = facSide.GetSide(Convert.ToInt32(Session["SideID"]));
        if (propSide != null)
        {
            txtHeadline.Text = propSide.Navn;
            txtText.Text = propSide.Tekst;
        }

    }

    protected void btnOK_Click(object sender, EventArgs e)
    {
        lblError.Visible = true;
        //    lblError.Text = txtHeadline.Text;
    }
}

og jeg har kun 2 usercontroller mere.
Den du ser når siden starter, den med de tre links i , og så en med simpel tekst i.
Avatar billede neoman Novice
21. oktober 2007 - 01:02 #34
Hvsi du kommenterer
        if (ViewState["mitKontrolnavn"] != null)
        {
            reloaded = Convert.ToBoolean(ViewState["mitKontrolnavn"]);
        } 
ud så burde den komme med NOTCallback:)

derpå,
        if (ViewState["mitKontrolnavn"] != null)
        {
            reloaded = false;
        } 

så ser vi havd der sker:=

og derpå:

        if (ViewState["mitKontrolnavn"] != null)
        {
          reloaded = (Boolean)(ViewState["mitKontrolnavn"]);
        }
Avatar billede kennedk Nybegynder
21. oktober 2007 - 01:07 #35
if (ViewState["mitKontrolnavn"] != null)
        {
          reloaded = (Boolean)(ViewState["mitKontrolnavn"]);
        }

og

if (ViewState["mitKontrolnavn"] != null)
        {
            reloaded = Convert.ToBoolean(ViewState["mitKontrolnavn"]);
        } 

giver samme resultat :O)

Men er der ikke en anden metode til at loade de usercontrols uden postback på ? det ville jo være det optimale.
Avatar billede neoman Novice
21. oktober 2007 - 01:11 #36
jamen hvad gav de første to ?
Avatar billede kennedk Nybegynder
21. oktober 2007 - 01:12 #37
if (ViewState["mitKontrolnavn"] != null)
        {
            reloaded = false;
        } 
gav NOTcallback

og de andre to gav callback
Avatar billede neoman Novice
21. oktober 2007 - 01:14 #38
nej det kan du ikke  postback mekanikken er jo en del af systemet som du ikke bare kan smide ud. Det eneste du kan gøre er at holde styr på hvad du laver.

En anden metode må være at du selv styrer det derfra hvor du loader kontrollen. Lav en public property på kontrollen som har samme funktion som reload variablen nu, og så kan du sætte den til false i den kode som loader kontrollen og til false de efterfølgende gange
Avatar billede kennedk Nybegynder
21. oktober 2007 - 01:19 #39
Jeg takker begge to :) jeg vil sidde og lege videre med det i morgen.
Jeg synes det er fair at i begge ligger svar. hvad synes i?
Avatar billede neoman Novice
21. oktober 2007 - 01:22 #40
Tjoh - problemet er ikke løst så jeg vil hellere nøjes med dit tak for nu. Dr_chaos er helt sikkert i stand til svare for sig selv:)

Men, fatter stadig ikke at det ikke funker (selv om selv hvis det virkede, så måtte vi nok modificere det en del da du har alt kørende i en aspx side)..

God nat - man får masser af gode ideer mens man sover.)
Avatar billede kennedk Nybegynder
22. oktober 2007 - 09:59 #41
jeg har fundet mig en løsning :)

Når jeg trykker på menu punktet laver jeg en cookie:
function postBackIndhold(side,id) {
            var hiddenField = $get("<%=HiddenFieldToUpdateIndhold.ClientID %>");
            if (hiddenField) {
            if(document.cookie =  "postback=false; path=/;"){
                hiddenField.value = side + ";" + id;
                __doPostBack("<%=HiddenFieldToUpdateIndhold.ClientID %>",'');
            }
            }
        }


så når jeg kører usercontrollen tjekker jeg om cookien er lavet, og hvis den er det, er det ikke postback, og så sletter jeg den..


protected void Page_Load(object sender, EventArgs e)
    {
        if (Request.Cookies["postback"].Value == "false")
        {
            propSide propSide = facSide.GetSide(Convert.ToInt32(Session["SideID"]));
            if (propSide != null)
            {
                txtHeadline.Text = propSide.Navn;
                txtText.Text = propSide.Tekst;
            }
            Response.Cookies["postback"].Value = "true";
        }
    }
Avatar billede kennedk Nybegynder
22. oktober 2007 - 10:00 #42
Ups glemte svar
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester