Toon posts:

[ASP.NET/C#] - Alle panels opvragen

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik heb momenteel een ASPX pagina, de achterliggende code is in C#.

Ik heb op deze pagina een aantal panels staan en ik heb nu een stukje code nodig waar ik al die panels mee op kan vragen. Dit lijkt mij heel makkelijk, maar op google en hier (search) kon ik niets vinden.

Dit heb ik tot nu toe:

code:
1
2
3
4
5
6
7
8
9
10
ControlCollection c = this.Controls;
IEnumerator enumerator = c.GetEnumerator();
Object o;
String s="";
while (enumerator.MoveNext()) 
{
    o=enumerator.Current;
    s=s+" "+o.GetType().ToString();
}
ShowMessage(s);

In de message die verschijnt komen 3 types: WebBasedLiteralControl, HtmlForm en LiteralControl. Als ik kijk welke methoden/properties deze types hebben, zie ik geen nuttige (alleen Equals en ReferenceEquals). Ik zal dus een andere methode nodig hebben om de controls op te vragen, zodat ik alle Panels daar uit kan filteren.

Ik zal wel op de verkeerde keywords hebben gezocht, maar ik kan echt geen oplossing vinden voor mijn probleem, vandaar dit topic.

  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 27-04 18:17

gorgi_19

Kruimeltjes zijn weer op :9

Wanneer voer je deze actie uit? En waarom reference je niet per ID?

Digitaal onderwijsmateriaal, leermateriaal voor hbo


Verwijderd

Topicstarter
Ik heb een button gemaakt op de pagina die deze functie aanroept, dus na het initialiseren.

Wat bedoel je met je tweede vraag?? Dit is puur een testfunctie om te kijken of de panels ook worden opgevraagd m.b.v. this.Controls, wat dus niet het geval is.
gorgi_19 schreef op maandag 19 september 2005 @ 10:45:
Wanneer voer je deze actie uit? En waarom reference je niet per ID?

  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 27-04 18:17

gorgi_19

Kruimeltjes zijn weer op :9

Visual Basic .NET:
1
Dim p as Panel = DirectCast(Me.FindControl(idvanjecontrol),Panel)


En kijk anders eens met trace.axd :)

[ Voor 44% gewijzigd door gorgi_19 op 19-09-2005 10:49 ]

Digitaal onderwijsmateriaal, leermateriaal voor hbo


Verwijderd

Topicstarter
Probleem is dus dat ik niet de id weet. Ik wil gewoon alle panels hiden als op die knop wordt gedrukt. Ik kan wel elke keer een id toevoegen als ik een nieuw panel toevoeg, maar het lijkt me netter en handiger dat ik runtime alle panels opvraag.

Trace.axd heb ik nog nooit van gehoord, kan ik daarmee het probleem ook oplossen?

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Dit komt omdat Controls in een geneste structuur zitten. Als je van dat HtmlForm weer de child controls opvraagt zul je al een stuk verder komen

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Verwijderd

Topicstarter
Dat heb ik net geprobeerd en dan krijg ik weer 3 html-forms 8)7

Nevermind, tikfoutje... Ik krijg nu idd een aantal panels terug in de message!

De code die wel werkt:

code:
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
ControlCollection cc1 = this.Page.Controls;
System.Web.UI.HtmlControls.HtmlForm hf;
IEnumerator enum1 = cc1.GetEnumerator();
Object o1; 
while (enum1.MoveNext()) 
{
    o1=enum1.Current;
    if (o1.GetType().ToString()=="System.Web.UI.HtmlControls.HtmlForm") 
    {
        hf = (System.Web.UI.HtmlControls.HtmlForm) o1;
        ControlCollection cc2 = hf.Controls;
        IEnumerator enum2 = cc2.GetEnumerator();
        Object o2; 
        System.Web.UI.WebControls.Panel p;
        while (enum2.MoveNext()) 
        {
            o2=enum2.Current;
            if (o2.GetType().ToString()=="System.Web.UI.WebControls.Panel") 
            {
                p = (System.Web.UI.WebControls.Panel) o2;
                p.Visible=false;
            }
        }
        this.LoginPanel.Visible=true;
    }
}

Bedankt!

[ Voor 113% gewijzigd door Verwijderd op 19-09-2005 11:23 ]


  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 15:39

pjvandesande

GC.Collect(head);

Verwijderd schreef op maandag 19 september 2005 @ 11:15:
code:
1
2
3
4
5
IEnumerator enum1 = cc1.GetEnumerator();
Object o1; 
while (enum1.MoveNext()) 
{
    // ...
Waarom gebruik je geen foreach?

Verwijderd

Topicstarter
If it ain't broken, don't fix it :).

Dat is wel korter, maar het werkt nu wel.

  • EleFanta
  • Registratie: Juli 2000
  • Laatst online: 23-01-2024
foreach is wat kostbaarder.
Op jou manier vind je nu geen panels die in de controls collectie zitten van andere controls, eigenlijk wil je dit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
private void HidePanels(IEnumerator controls)
{
 while (controls.MoveNext()) 
 {
  if ( controls is Panel )
  {
   ((Panel)controls).Visible = false;
  }
  if (controls.HasControls())
  {
   HidePanels(controls.controls.GetEnumerator();
  }
 }
}


Ik heb geen VS op deze pc dus kan zijn dat ik nog ergens een foutje heb staan, maar die vind je snel genoeg na een build.

[ Voor 10% gewijzigd door EleFanta op 19-09-2005 14:13 ]


Verwijderd

Topicstarter
het moet iets anders, maar dan nog krijg ik errors:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private void HidePanels(IEnumerator controls)
{
    while (controls.MoveNext()) 
    {
        
        if (controls.Current is System.Web.UI.WebControls.Panel)
        {
            ((System.Web.UI.WebControls.Panel)controls.Current).Visible = false;
        }
        if (controls.Current.HasControls())
        {
            HidePanels(controls.Current.GetEnumerator());
        }
    }
}

Current.HasControls werkt niet, aangezien ik heb ergens heen moet typecasten. Dit is moeilijk, aangezien je niet weet wat voor type het is... Je moet dus run-time het type bepalen en hem daarheen typecasten, maar dat kan volgens mij niet :).

Mijn stukje code werkt wel en meer panels krijg ik wss niet, dus het is ook niet nodig eigenlijk.

  • EleFanta
  • Registratie: Juli 2000
  • Laatst online: 23-01-2024
Je hebt gelijk. Mijn fout, best lastig zonder VS.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private void HidePanels(IEnumerator controls)
{
    while (controls.MoveNext()) 
    {
        
        if (controls.Current is System.Web.UI.WebControls.Panel)
        {
            ((System.Web.UI.WebControls.Panel)controls.Current).Visible = false;
        }
        if ( ((Control)controls.Current).HasControls())
        {
            HidePanels(controls.Current.GetEnumerator());
        }
    }
}

Je kunt het altijd naar een control casten en daar kun je aan vragen of hij controls heeft.

  • whoami
  • Registratie: December 2000
  • Laatst online: 15:31
En eigenlijk is het beter om zo te casten:
code:
1
2
3
4
5
6
System.Web.UI.WebControls.Panel p = controls.Current as System.....WebControls.Panel;

if( p != null )
{
   p.Visible = false;
}

Op die manier hoef je maar 1 keer te 'casten'. Bij jouw code check je eerst of een control wel van een bepaald type is, en zoja, dan ga je casten. Ik doe het in één keer, met de as operator. Die returned gewoon null als het object niet van het gewenste type is.

https://fgheysels.github.io/


Verwijderd

Topicstarter
EleFanta schreef op maandag 19 september 2005 @ 14:29:
Je hebt gelijk. Mijn fout, best lastig zonder VS.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private void HidePanels(IEnumerator controls)
{
    while (controls.MoveNext()) 
    {
        
        if (controls.Current is System.Web.UI.WebControls.Panel)
        {
            ((System.Web.UI.WebControls.Panel)controls.Current).Visible = false;
        }
        if ( ((Control)controls.Current).HasControls())
        {
            HidePanels(controls.Current.GetEnumerator());
        }
    }
}

Je kunt het altijd naar een control casten en daar kun je aan vragen of hij controls heeft.
Maak van de typecast dan wel System.Web.UI.Control, Control wordt gezien als ambigu (ik heb het niet getest, het werkt nu iig).

  • EleFanta
  • Registratie: Juli 2000
  • Laatst online: 23-01-2024
Ik ben ook geen voorstander van de code die ik heb geschreven. Als het niet leesbaar is dan is het niet goed.
Dit was even snel uit me mouw geschud. Maar met alle stukjes code die er nu staan kan er wel een mooi stukje dynamische code geschreven worden.
@whoami: Die was ik alweer vergeten :X Daarmee wordt het nog beter.

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 15:39

pjvandesande

GC.Collect(head);

Release build?

Ik vind overigens dat leesbaarheid van je code voor snelheid gaat als het geen grootte inpakt heeft natuurlijk.

Er hangt hier ergens een draadje in /14 over is and as met wat MSIL code met wat sneller is, er staat mij iets bij dat is beter uit de boot kwam omdat er niet op null value gechecked hoeft te worden. Waarbij as weer sneller is al het inderdaad van dat type is.

Maargoed, mocht je dit soort dingen intressant vinden dan bekijk je zelf even de MSIL code.

[ Voor 42% gewijzigd door pjvandesande op 19-09-2005 15:02 ]


  • EleFanta
  • Registratie: Juli 2000
  • Laatst online: 23-01-2024
Ik gebruik zelf ook erg graag de foreach en veel scheelt het niet.
Leesbaarheid is in mijn ogen ook heel belangrijk. Maar met goede naamgeving kun je met de enumerator net zulke leesbare code schrijven als de foreach. Het is ook een kwestie van gewenning, als je iets nooit gebruikt zal het de eerste keer ook minder prettig lezen.

  • whoami
  • Registratie: December 2000
  • Laatst online: 15:31
:?
Foreach roept toch ook de enumerator aan ? Ik zie dus niet in waarom het doorlopen van de enumerator via de while 'performanter' zou zijn, dan mbhv foreach ?
Wie zegt trouwens dat de compiler / CLR hier niet exact dezelfde instructies gaat voor genereren ?

Misschien ff checken met msildasm

https://fgheysels.github.io/


  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 15:39

pjvandesande

GC.Collect(head);

Nee, dus:
C#:
1
2
3
4
5
6
7
8
[STAThread]
static void Main(string[] args)
{
    foreach(string arg in args)
    {
        Console.WriteLine( arg );
    }
}

Resulteerd in:
code:
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
29
30
31
.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  .custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 ) 
  // Code size       27 (0x1b)
  .maxstack  2
  .locals init ([0] string arg,
           [1] string[] CS$00000007$00000000,
           [2] int32 CS$00000008$00000001)
  IL_0000:  ldarg.0
  IL_0001:  stloc.1
  IL_0002:  ldc.i4.0
  IL_0003:  stloc.2
  IL_0004:  br.s       IL_0014
  IL_0006:  ldloc.1
  IL_0007:  ldloc.2
  IL_0008:  ldelem.ref
  IL_0009:  stloc.0
  IL_000a:  ldloc.0
  IL_000b:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_0010:  ldloc.2
  IL_0011:  ldc.i4.1
  IL_0012:  add
  IL_0013:  stloc.2
  IL_0014:  ldloc.2
  IL_0015:  ldloc.1
  IL_0016:  ldlen
  IL_0017:  conv.i4
  IL_0018:  blt.s      IL_0006
  IL_001a:  ret
} // end of method Class1::Main

En de enumerator code:
C#:
1
2
3
4
5
6
7
8
9
10
[STAThread]
static void Main(string[] args)
{
    IEnumerator enumerator = args.GetEnumerator();

    while(enumerator.MoveNext())
    {
        Console.WriteLine( enumerator.Current );
    }
}

Resulteerd in:
code:
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
29
30
31
.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  .custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 ) 
  // Code size       27 (0x1b)
  .maxstack  2
  .locals init ([0] string arg,
           [1] string[] CS$00000007$00000000,
           [2] int32 CS$00000008$00000001)
  IL_0000:  ldarg.0
  IL_0001:  stloc.1
  IL_0002:  ldc.i4.0
  IL_0003:  stloc.2
  IL_0004:  br.s       IL_0014
  IL_0006:  ldloc.1
  IL_0007:  ldloc.2
  IL_0008:  ldelem.ref
  IL_0009:  stloc.0
  IL_000a:  ldloc.0
  IL_000b:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_0010:  ldloc.2
  IL_0011:  ldc.i4.1
  IL_0012:  add
  IL_0013:  stloc.2
  IL_0014:  ldloc.2
  IL_0015:  ldloc.1
  IL_0016:  ldlen
  IL_0017:  conv.i4
  IL_0018:  blt.s      IL_0006
  IL_001a:  ret
} // end of method Class1::Main

Dit is wel met een release build, debug zou nog wel kunnen verschillen. Maar met release dus identiek.

[ Voor 7% gewijzigd door pjvandesande op 19-09-2005 16:36 ]

Pagina: 1