Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[ASP.NET] Updatepanels in usercontrol hebben zelfde clientId

Pagina: 1
Acties:

  • 4of9
  • Registratie: Maart 2000
  • Laatst online: 13-12-2024
Hallo,

Ik loop net tegen iets vreemds aan waar ik zo even geen antwoord op weet, en ik dus hoop of jullie mij kunnen helpen.

Ik heb een usercontrol dat geladen (meerdere keren) word in een updatepanel (ASP.NET Ajax). Dat gaat allemaal prima. Dit usercontrol bevat echter zelf ook weer een updatepanel. Dit panel heeft als ID pnl (decleratief gedefinieerd).

Nu heb ik de clientId's van die panels nodig. Ik expose dus op het usercontrol deze clientID's via een property PanelClientID. Die property returned op zijn beurt een this.pnl.ClientID.

Het rare is nu dat dit allemaal goed werkt alleen heb ik in mijn geval een pagina waarop 4x het usercontrol is geladen en als ik nu die ClientID's van de panels uitlees zijn ze echter alle 4 pnl, ook de UniqueID is pnl. Dit zou toch voorkomen moeten worden door de namingContainer?

Hoe kan ik dit gedrag voorkomen of wat doe ik fout?

Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...


  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Maar het is per definitie al niet handig om 4 controls dezelfde naam te geven. Maar elk panel welke je gebruikt heeft een functie (doel), dus waarom gebruikt je geen beschrijvende panel id's. Hoe geef je aan een collega aan welke control je bedoeld als meerdere dezelfde naam hebben?

Dus begin met alle panels een eigen naam (id) te geven.

If it isn't broken, fix it until it is..


  • 4of9
  • Registratie: Maart 2000
  • Laatst online: 13-12-2024
Ik denk dat ik niet geheel duidelijk ben geweest.

Ik heb een usercontrol dat dynamisch meerdere keren geladen word. Dat usercontrol bevat een panel. En dat panel heeft een ID. Ik kan dat panel dus geen uniek ID geven al zou ik willen.

Dit is een zeer veel voorkomende contructie hoor.

Alleen normaal krijgen alle server controls automatisch een unieke client id, en nu dus niet.

[ Voor 24% gewijzigd door 4of9 op 21-09-2007 14:01 ]

Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...


  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Normaal krijgt een control een ID en naam waarin de parentcontrols zijn opgenomen. Verder moet je van het panel (in de aspx) alleen het ID property zetten.

code:
1
2
3
4
5
6
7
8
9
10
<form id="form1" runat="server">
<asp:UpdatePanel ID="panel1">
  <asp:button ID="decrease" Text="-" runat="server" onClick="panel1_decrease" />
  <asp:button ID="increase" Text="-" runat="server" onClick="panel1_increase" />
</asp:UpdatePanel>
<asp:UpdatePanel ID="panel2">
  <asp:button ID="decrease" Text="-" runat="server" onClick="panel2_descrease" />
  <asp:button ID="increase" Text="-" runat="server" onClick="panel2_increase" />
</asp:UpdatePanel>
</form>

Dit werkt bij mij perfect. Alle controls krijgen een uniek ID zoals panel1_increase. Als ik auto postback op true zet, wordt de referentie panel1:increase bij doPostback gebruikt. Zelfs als ik een tweede panel object binnen de eerste panel plaats gaat dit gewoon correct.

Het enigste wat ik je kan aanraden is een lege aspx te maken en daar alleen enkelvoudig je usercontrol (met ID 'uc1') op te plaatsen en de html source te controleren. Plaats vervolgens een tweede instantie (uc2) van je usercontrol op de page. In mijn geval kreeg ik vervolgens benamingen zoals uc1_panel1_increase en uc2_panel1_increase.

If it isn't broken, fix it until it is..


  • 4of9
  • Registratie: Maart 2000
  • Laatst online: 13-12-2024
Ik waardeer je poging om mij te helpen maar dit is een totaal andere situatie die je beschrijft.

Ik weet dat normaal je controls aparte id's krijgen maar nu dus niet en ik vroeg me af of iemand hier ervaring mee heeft.

Ik zal het nog een keer proberen te verduidelijken:

- Ik heb een usercontrol met een updatepanel
- dit update panel heeft als ID: pnl
- Dit usercontrol wordt dmv load control aan een updatepanel op een pagina toegevoegd. (1 of meerdere keren)
- als ik nu de clienID's van de updatepanels in de usercontrol opvraag zijn deze allemaal hetzelfde, namelijk "pnl".

Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...


  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 22:16

gorgi_19

Kruimeltjes zijn weer op :9

Heb je voorbeeldcode? Want pnl als ClientId vind ik enigszins vreemd :)

Digitaal onderwijsmateriaal, leermateriaal voor hbo


  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Zelfs als ik in plaats van declarative de twee panels met daarin de buttons dynamisch toevoeg gaat dit bij mij (zowel VS2005 (SP1) met .NET 3.0) als VS2008 (Beta 2) gewoon goed.

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//load event van control (MyPanel.ascx.cs)
UpdatePanel panel1 = new UpdatePanel();
panel1.ID = "panel1"; // <-- erg belangrijk

Button increase = new Button();
increase.ID = "increase";
increase.Click += new EventHandler(panel1_increase_click);
panel1.Controls.Add(increase);

Button decrease = new Button();
decrease.ID = "increase";
decrease.Click += new EventHandler(panel1_decrease_click);
panel1.Controls.Add(decrease);

//hier komt panel2 opbouw

this.Controls.Add(panel1); // this verwijst naar usercontrol (MyPanels.ascx(.cs))
this.Controls.Add(panel2);

//page load event (panels.aspx.cs)
MyPanel uc1 = (MyPanel) LoadControl("MyPanel.ascx");
uc1.ID = "uc1";

MyPanel uc2 = (MyPanel) LoadControl("MyPanel.ascx");
uc2.ID = "uc2";

this.Controls.Add(uc1); 
this.Controls.Add(uc2); 


Bovenstaande code werkt zoals gezegd bij mij net zogoed als de eerder vermelde declarive code. Ook de ID benamingen in de html output staan correct.

If it isn't broken, fix it until it is..


  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 22:16

gorgi_19

Kruimeltjes zijn weer op :9

Waarom plaat je die in je load event en niet tijdens CreateChildControls / Init? :)

Digitaal onderwijsmateriaal, leermateriaal voor hbo


  • 4of9
  • Registratie: Maart 2000
  • Laatst online: 13-12-2024
Ik zal maandag wel even wat code posten (zit niet meer op mijn werk)

Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...


  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

ClientID blijft inderdaad 'pnl' wat die optie is voornamelijk bedoeld voor gebruik in repeaters. Middels ClientID kunt je dan je control weer terug 'vinden'.

Probeer eens UniqueID ipv ClientID. UniqueID bevat naam zoals deze gebruikt zal worden in de HTML output. Houd er wel rekening mee, dan deze naam pas volledig is als alle controls aan elkaar zijn toegekend.

Ik dacht namelijk dat je de control van javascript (client sided - je gebruikte de term ajax) probeerde te benaderen. Maar blijkbaar gaat het om de javascript welke server sided wordt gegenereerd.

If it isn't broken, fix it until it is..


  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 22:16

gorgi_19

Kruimeltjes zijn weer op :9

Niemand_Anders schreef op vrijdag 21 september 2007 @ 16:42:
ClientID blijft inderdaad 'pnl' wat die optie is voornamelijk bedoeld voor gebruik in repeaters. Middels ClientID kunt je dan je control weer terug 'vinden'.

Probeer eens UniqueID ipv ClientID. UniqueID bevat naam zoals deze gebruikt zal worden in de HTML output. Houd er wel rekening mee, dan deze naam pas volledig is als alle controls aan elkaar zijn toegekend.

Ik dacht namelijk dat je de control van javascript (client sided - je gebruikte de term ajax) probeerde te benaderen. Maar blijkbaar gaat het om de javascript welke server sided wordt gegenereerd.
:?
The ClientID value generated for a control is identical to the UniqueID value, except that an underscore character is used to delimit the ID values, instead of the character specified by the IdSeparator property. By default, the IdSeparator property is set to a colon character (:). Because the ClientID value does not contain colon characters, it can be used in ECMAScript, which does not support IDs containing colons.
* gorgi_19 kan het verhaal wat je nu houdt niet echt rijmen met wat de specificatie zegt :)

Digitaal onderwijsmateriaal, leermateriaal voor hbo


  • 4of9
  • Registratie: Maart 2000
  • Laatst online: 13-12-2024
Ok ik zou nog wat code posten om het een en ander te verduidelijken.

ik heb een pagina (noem hem even mijnpagina.aspx) met een updatepanel en daar wordt dynamish een usercontrol in geladen (uc1):

C#:
1
2
3
4
5
6
7
8
9
protected void UpdatePanel_OnLoad(object sender, EventArgs e)
{

            string controlPath = "~/usercontrols/uc1.ascx";
            Control uc = this.LoadControl(controlPath);
     
            UpdatePanel.ContentTemplateContainer.Controls.Add(uc);

}


Dat usercontrol benaderd onze database en haalt daar gegevens op.
Voor iedere record maakt hij een nieuwe usercontrol aan (uc2).

C#:
1
2
3
4
5
6
7
  foreach (string record in dt.Rows)
        {

            Control uc2= this.LoadControl("~/usercontrols/uc2.ascx");

            this.Controls.Add(uc2);
        }     



dit usercontrol (uc2) bevat ook weer een UpdatePanel genaamd (ID) "pnl":

uc2 gaat vervolgens weer naar de database en haalt daar wat gegevens op en voegt deze toe aan "zijn" update panel:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  protected override void OnInit(EventArgs e)
    {
        //haal info op uit db
        DataTable dt = _dal.GetControlsOnPlaceHolder(_pageId, _placeHolder);

        foreach (DataRow row in dt.Rows)
        {
           //fake new control met info uit database
           Control c = new LiteralControl();

            pnl.ContentTemplateContainer.Controls.Add(control);
        }

        base.OnInit(e);
    }


Zoals eerder gezegd werkt dit prima, op 1 dingetje na.
De panels ("pnl") in uc2 krijgen geen unieke clientID wat wel gebruikelijk is. En ik heb die ClientID wel nodig om de updatepanels aan te kunnen spreken via een javascript (updatepanels renderen als divs)

Er zijn dus meerdere uc2's geladen en dus evenveel updatepanels met het ID "pnl" alleen heten ze allemaal "pnl" aan de client kant. Ook het uniqueID is pnl (maar ik moet echt clientID hebben)

Ik hoop dat iemand mij hiermee verder kan helpen, want ik kan op internet niets vinden over dit gedrag.

Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...


  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Je geeft de dynamisch aangemaakt controls geen ID. Omdat jij geen ID opgeeft, zal de get ook geen ID terug geven. Echter wordt er voor de HTML wel een ID gegenereerd. Je zult dus een regel moeten toevoegen zoals uc.ID= "contentTemplate";

Omdat alleen het panel een ID heeft gekregen, is dat ook direct het enigste wat ClientID of UniqueID kan terug geven. In mijn code voorbeeld heb ik op regel 2 al aangegeven dat het ID heel erg belangrijk is.

Voeg eerst eens aan de dynamisch toegevoegde controls een ID toe (het ID wordt immers gebruikt voor het opbouwwen van zowel het ClientID en UniqueID path.

Wat betreft mijn vorige post. Gorgi heeft gelijk, ik haald UniqueID en ClientID door elkaar. Excuses, sorry en ik zal het niet meer doen!

If it isn't broken, fix it until it is..


  • 4of9
  • Registratie: Maart 2000
  • Laatst online: 13-12-2024
Ik heb geprobeerd wat je hebt gezegd en ook dat bied geen soelaas.

De ClientID veranderd wel alleen zijn ze nog steeds niet uniek, maar een concatenering van de opgegeven id ("block" in mijn geval) en de ID van de pnl wat dus resulteerd in "block_panel" als clientID voor alle 4 de panels.

Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...


  • 4of9
  • Registratie: Maart 2000
  • Laatst online: 13-12-2024
Ik heb het gevonden.

Het lag eraan dat ik de clientID opvroeg voor dat de control toegevoegd was.

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
foreach (string placeHolder in _templatePlaceholderHandler.PlaceHolders)
        {

            IPlaceHolderEditorBlock block = this.LoadControl("~/poc/usercontrols/editor/placeholdereditorblock.ascx") as IPlaceHolderEditorBlock;
        
            block.PlaceHolder = placeHolder;
            block.PageId = _pageId;
            block.IsSave = _isSave;

            if (counter > 0)
            { 
                arrBuilder.Append(",");
            }
            arrBuilder.Append("'");
            arrBuilder.Append(block.PanelClientID);
            arrBuilder.Append("'");
           
             this.Controls.Add((Control)block);
            counter++;
        }     


is geworden:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
foreach (string placeHolder in _templatePlaceholderHandler.PlaceHolders)
        {

            IPlaceHolderEditorBlock block = this.LoadControl("~/poc/usercontrols/editor/placeholdereditorblock.ascx") as IPlaceHolderEditorBlock;
        
            block.PlaceHolder = placeHolder;
            block.PageId = _pageId;
            block.IsSave = _isSave;

            this.Controls.Add((Control)block);

            if (counter > 0)
            { 
                arrBuilder.Append(",");
            }
            arrBuilder.Append("'");
            arrBuilder.Append(block.PanelClientID);
            arrBuilder.Append("'");
           
             
            counter++;
        }     

Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...

Pagina: 1