Avatar billede CodingJoe Nybegynder
04. august 2011 - 09:03 Der er 32 kommentarer og
1 løsning

Dynamisk indlæsning af .ascx (usercontrols)

Jeg har en UserControl - Lad os kalde den for 'main.ascx'.
I denne 'main.ascx' usercontrol indlæser jeg dynamisk diverse andre usercontrols.

Jeg har en løkke hvori jeg indlæser en liste af usercontrols og loader dem ind vha.
var ctrl = LoadControl(myUsercontrolName);

Nu er det interessant hvordan jeg i 'main.ascx' kan have adgang til mine asp.net kontroller fx. mine knapper eller andre kontroller...

Skal jeg prøve at bruge noget nedarvning for at få adgang til mine under usercontrols?

I så fald hvordan gør man det? Det meste virker efter hensigten...men jeg har bare ikke adgang fra main.ascx til fx. mine TextBox'es i mine under usercontrols. 

Det vil være ret fedt, hvis det kan lade sig gøre...
Avatar billede mjdigital Nybegynder
04. august 2011 - 09:47 #1
Forstår ikke helt hvorfor du vil have adgang til de forskellige tekst-bokse osv. når der allerede er tilknyttet en CS fil som helt fint styre det.

myControl ctrl =(myControl)LoadControl("main.ascx");
myControl.someProperty = "something"

Prøv dog dette, burde virkede har dog ikke testet.
Avatar billede CodingJoe Nybegynder
04. august 2011 - 10:34 #2
Det er altid svært at forklare på skrift, så det stadigvæk kan forstås...jeg har lavet nedenstående illustration / pseudokode. Håber det hjælper på forståelsen af det, jeg prøver at opnå ;)

------------------

<usercontrolA.ascx>
<asp:textbox name="mintextboxA" />
</usercontrolA.ascx>

------------------

<usercontrolB.ascx>
<asp:textbox name="mintextboxB" />
</usercontrolB.ascx>

------------------

<main.ascx>

Løkke[start]
//Indlæser usercontrolA + usercontrolB
myControl ctrl =(myControl)LoadControl(usercontrolA + usercontrolB);
Løkke[slut]

//Hvordan kan jeg få adgang til mintextboxA og mintextboxB herfra?

</main.ascx>

--------------------
Avatar billede CodingJoe Nybegynder
04. august 2011 - 11:18 #3
Jeg har forsøgt med var control = (TextBox) Page.FindControl("mintextboxA");

Men min control er null :(

Spørgsmålet om det er FindControl eller noget helt andet, jeg skal forsøge med i min main.ascx...
Avatar billede kalp Novice
04. august 2011 - 11:23 #4
Du skal nok angive præcist hvilken kontrol det er.. og altså ikke benytte "var" eller "Control" eller hvad det nu er for en de arver fra.

noget lignende det her vil virke.

        foreach (Control control in controls) //med controls mener jeg den liste hvor du har ControlA og ControlB.
        {
            ControlA controlA = control as ControlA;
            if (controlA != null)
            {
                controlA.TextBoxA.Text = "Jeg fandt A";
                break;
            }
            ControlB controlB = control as ControlB;
            if (controlA != null)
            {
                controlB.TextBoxB.Text = "Jeg fandt B";
                break;
            }
        }
Avatar billede CodingJoe Nybegynder
04. august 2011 - 11:27 #5
var ctrl = LoadControl("usercontrolA.ascx");
var mintextboxA = (TextBox)ctrl.FindControl("mintextboxA");
var vaerdi = mintextboxA.Text;

Jeg kan få adgang til 'mintextboxA', men 'vaerdi' er tom streng, selvom jeg har sat en default værdi i 'mintextboxA'.
Avatar billede kalp Novice
04. august 2011 - 11:29 #6
Jeg har ikke tested det med "var", så jeg gætter bare på at den måske går ind og finder "UserControl" og så kan du ikke tilgå dens elementer direkte..
Du skal også lige huske at gøre dine elementer public.

Hvis du gør det så virker ovenstående.
Avatar billede CodingJoe Nybegynder
04. august 2011 - 11:41 #7
I min 'usercontrolA.ascx.designer.cs' har jeg forsøgt at gøre min textbox public:

public global::System.Web.UI.WebControls.TextBox mintextboxA;

Men det hjalp ikke :/

Tror du har ret...jeg indlæser blot en 'kopi' af 'usercontrolA.ascx' og derfor vil min 'mintextboxA' holde en tom værdi, selvom jeg har lagt en default værdi i den.

Tricket skal være at kunne tilgå 'mintextboxA' feltet og hente værdien ud enten under en Page_Load på main.ascx eller i en MinSubmitBtn_Click event:

* Main.ascx.cs *
protected void Page_Load(object sender, EventArgs e) {
  var ctrl = LoadControl("usercontrolA.ascx");
  var mintextboxA = (TextBox)ctrl.FindControl("mintextboxA");
  var vaerdi = mintextboxA.Text;
  // vaerdi er tom :(
}
-------------
protected void MinSubmitBtn_Click(object sender, EventArgs e){
  var ctrl = LoadControl("usercontrolA.ascx");
  var mintextboxA = (TextBox)ctrl.FindControl("mintextboxA");
  var vaerdi = mintextboxA.Text;
  // vaerdi er tom :(
}
Avatar billede kalp Novice
04. august 2011 - 11:47 #8
læser lige din kommentar..

imens kan du hente et eksempel herfra, som jeg har lavet.

http://minprofil.dk/gusa/

bare klik på download ikonet på siden.
Avatar billede kalp Novice
04. august 2011 - 11:52 #9
I mit eksempel er textboxa tom, men jeg har lige tested hvor jeg skriver denne kode på kontrollen istedet:

    if(!IsPostBack)
        {
            TextBoxA.Text = "start værdi";
            Controls.Add(TextBoxA);
        }

og selvfølgelig lige sletter denne linje i default.aspx

        ctl.TextBoxA.Text = "hejsa";

og det virker stadig:)

håber du ud fra mit eksempel kan se hvad du gør forkert:)
Avatar billede CodingJoe Nybegynder
04. august 2011 - 11:53 #10
Ja, meget fint eksempel...men problemet er ikke at tildele en værdi på min textbox. Det er efterfølgende under en submit at hente den indtastede / default værdi ud igen. :)
Avatar billede CodingJoe Nybegynder
04. august 2011 - 11:54 #11
Hmmm lad mig lige kigge...

Mit eksempel har jeg dog nested usercontrols...men det bør være det samme...
Avatar billede kalp Novice
04. august 2011 - 12:00 #12
Hvis du har angivet din startværdi på markup siden, så prøv at gøre det fra din code behind fil istedet.. under page load på din usercontrol:)
Avatar billede kalp Novice
04. august 2011 - 12:01 #13
hvis du har angivet din start værdi i markup koden, så prøv at gøre det i din code behind under page load på din usercontrol:)
Avatar billede CodingJoe Nybegynder
04. august 2011 - 12:03 #14
Ja, det er faktisk, det jeg har gjort. Det var mest for at undgå at submitte siden hver gang for at teste min kode.

Tror jeg er tæt på.
Avatar billede kalp Novice
04. august 2011 - 12:04 #15
du skal bare ligge din kode ind i if(!isPostBack), som i mit eksempel:)
Avatar billede CodingJoe Nybegynder
04. august 2011 - 12:12 #16
Stadigvæk tomt.

Prøv at lave en Default.aspx hvori du har en main.ascx.

I main.ascx.cs under page_load indlæs din userControlA.ascx.
og indsæt en <asp:Button ID="SubmitBtn" runat="server" Text="Send"
    onclick="SubmitBtn_Click" /> i markup filen (main.ascx).

I din userControlA.ascx har du en <asp:TextBox name="mytextbox">

I din main.ascx.cs har du:
protected void SubmitBtn_Click(object sender, EventArgs e)
{
    var ctrl = LoadControl("userControlA.ascx");
    var mytextbox = (TextBox)ctrl.FindControl("mytextbox");
    var vaerdi = mytextbox .Text;
}
Avatar billede CodingJoe Nybegynder
04. august 2011 - 12:13 #17
Hvis min kode ligger i
protected void SubmitBtn_Click(object sender, EventArgs e)
{
}

Så er der vel posted?

Jeg kan prøve under if(!isPostBack)...det kan jo være min side / form slet ikke bliver posted....
Avatar billede CodingJoe Nybegynder
04. august 2011 - 12:22 #18
Jeg har prøvet med:

var ctrl = (Step01)Page.LoadControl("/Selvbetjening/Step01.ascx");
var forNavn = (TextBox)ctrl.FindControl("ForNavn");
var vaerdi = forNavn.Text;

i både
----------------------------
protected void Page_Load(object sender, EventArgs e)
{
if(IsPostBack){
  var ctl = (userControlA)Page.LoadControl("userControlA.ascx");
  var minTextBox = (TextBox)ctrl.FindControl("minTextBox");
  var vaerdi = minTextBox.Text;
}
}
-----------------------------
protected void SubmitBtn_Click(object sender, EventArgs e)
{
  var ctl = (userControlA)Page.LoadControl("userControlA.ascx");
  var minTextBox = (TextBox)ctrl.FindControl("minTextBox");
  var vaerdi = minTextBox.Text;
}

Begge gange er min vaerdi = ''. :S
Avatar billede CodingJoe Nybegynder
04. august 2011 - 12:23 #19
Se bort fra den øverste del...fik ikke rettet væerdierne...
Avatar billede kalp Novice
04. august 2011 - 12:54 #20
Ahh du har lagt det ind på en knap.. men problemet er at page load ikke bliver afviklet på din user control på det her tidspunkt.. derfor vil den være tom.

Du kan evt. lave en metode hvor i din user control, som du kan kalde fra din Main control:)
Avatar billede kalp Novice
04. august 2011 - 12:57 #21
Dvs.

UserControl i mit kunne se sådan her ud:
public partial class ControlA : System.Web.UI.UserControl
{
    public void Initialize()
    {
        TextBoxA.Text = "Start værdi";
    }
}

og i din kode:

protected void Page_Load(object sender, EventArgs e)
{
if(IsPostBack){
  var ctl = (userControlA)Page.LoadControl("userControlA.ascx");
  ctl.Initialize();
  var minTextBox = (TextBox)ctrl.FindControl("minTextBox");
  var vaerdi = minTextBox.Text;
}
}
Avatar billede CodingJoe Nybegynder
04. august 2011 - 13:07 #22
Ok...problemet er bare, at der ikke skal være nogen startværdi. Det er indtastede data, jeg gerne vil samle op i min main kontrol.

Jeg prøver mig lige frem...
Avatar billede kalp Novice
04. august 2011 - 13:15 #23
Du kan måske nøjes med at markere at værdierne skal læses fra kontrollen i Main kontrollen og vente med at læse dem ud til Main kontrollen kalder onPreRender.. (bare override metoden... den arves fra UserControl).

Jeg kan ikke huske rækkefølgende, men hvis den kalder page load på UserControlA før onPreRender bliver kaldt på Main controllen, så vil det virke..

om ikke andet så ved du hvad problemet er, så måske kan du komme frem til en løsning.. ellers kan jeg nok bikse noget sammen.
Avatar billede CodingJoe Nybegynder
04. august 2011 - 13:40 #24
Ja, jeg prøver mig lige frem. Håber du ligeledes kan se udfordringen...

Istedet for at samle indtastede værdier i de enkelte sub usercontrols, forsøger jeg at samle op på dem i en overordnet usercontrol inde i submit knappens OnClick event. :D
Avatar billede CodingJoe Nybegynder
04. august 2011 - 14:04 #25
Hmmm det er lidt interessant min submit knap i min main.ascx submitter tilsyneladende ikke værdier på min under userkontroller. Hvis jeg smider en submit knap ind i underuser kontrollen kan jeg tilgå værdierne i mine felter...
Avatar billede CodingJoe Nybegynder
04. august 2011 - 14:21 #26
Damn...har prøvet en del...men tror ikke det kan lade sig gøre... :S

Jeg troede en server side button altid fremprovokerer et post, men tilsyneladende kan jeg kun få fat i det indtastede indhold, hvis en button ligger i samme userkontrol som mine felter...smider jeg knappen ind i main.ascx så er der ingen værdi i feltet...
Avatar billede kalp Novice
04. august 2011 - 16:38 #27
Jeg er ærligt ikke helt sikker på hvad du prøver på:)
Det er måske ikke den rigtige løsning du vælger til dit problem.

Du kan dog hente værdierne på den gode gamle måde.

var textboxa = Request["idpåtextboxa"];

det virker da... husk at kigge i kildekoden efter dine id'er for at teste.
Du kan gøre det programmelt senere.. din usercontrol sætter prefix på dens elementer.
Avatar billede CodingJoe Nybegynder
04. august 2011 - 17:00 #28
Jeps...det var oprindeligt lavet på den gamle måde at requeste værdierne på, men så udnytter man ikke ikke ASP.Net fuldt ud. Jeg er klar over id'erne får et prefix, når man bruger asp.net kontrollerne...jeg finder en løsning, jeg giver ikke op...der skal måske vendes lidt rundt i min kode...

Sagen er helt enkelt...

man har en usercontrol som holder en hel masse andre userkontroller med felter.

Der indsættes en knap i hoved userkontrollen...og i hoved userkontrollens codebehind under (PostBack) eller i knappens Click Event samler noget logik alle felternes værdier....det må kunne lade sig gøre...
Avatar billede CodingJoe Nybegynder
04. august 2011 - 18:08 #29
Yes. Så var der hul igennem, lavede et eksempel derhjemme....problemet er at jeg skal traversere igennem kontrol hierakiet korrekt.

Det kunne være fedt, hvis man kan query controls hierakiet og finde den ønskede kontrol, som man så kan finde værdien udfra.
Avatar billede CodingJoe Nybegynder
04. august 2011 - 18:09 #30
...jeg kan vel bruge Linq til at snappe min control ud af Controls kollektionen... prøver lige...
Avatar billede CodingJoe Nybegynder
04. august 2011 - 18:49 #31
...og har lavet et Linq udtryk, der netop fanger den rigtige kontrol og udvinder den postede data...

fedt at det virker, når man holder en pause og kigger på det igen med friske øjne :)

Smid bare et svar ind... :)

Jeg smider mig Linq udtryk ind her, når jeg har fået det sidste på plads..

Tak for tiden :D
Avatar billede CodingJoe Nybegynder
04. august 2011 - 18:55 #32
I min Main.ascx
---------------------------------------------------------------
protected void SubmitBtn_Click(object sender, EventArgs e) {
var res1 = ((TextBox)Controls.OfType<Main>().Select(c => c).Single().Controls.OfType<MinSubControl>().Select(s => s.FindControl("MinTextBox")).Single()).Text;
}
Avatar billede CodingJoe Nybegynder
04. august 2011 - 21:17 #33
Så har jeg yderligere fået lavet en generic metode, der håndterer udvinding af værdierne:

protected void SubmitBtn_Click(object sender, EventArgs e) {
  var value = RetrieveValue<MinSubCntrl01, TextBox>("MinTextBox02").Text;
  var value2 = RetrieveValue<MinSubCntrl02, TextBox>("MinTextBox02").Text;
}

private TF RetrieveValue<T, TF>(string fieldName) where T : UserControl where TF : class {
            var res = Controls.OfType<Main>().Select(c => c).Single().Controls.OfType<T>().Select(s => s.FindControl(fieldName)).Single();
            return res as TF;
}

Ret elegant og stærkt!!
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
Kurser inden for grundlæggende programmering

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