Avatar billede madmital Nybegynder
28. oktober 2007 - 10:58 Der er 13 kommentarer

Usercontrols el. lign til dynamisk include af kode

Hej alle.

Ifm. med et igangværende projekt har jeg en ide, som jeg ikke ved om kan lade sig gøre...og så i givet hvordan.
Jeg vil gerne kunne inkludere objektdeklarationer fra forskellige eksterne filer i een fil's Page.Init-sektion efter behov.
Giver det mening?

Altså:
'*** default.aspx.vb
Partial Class _Default
  Inherits System.Web.UI.Page
  Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
      '*** Inkluder enten "fil1" eller "fil2" eller....afhængigt af eval af variabel
  End Sub
End Class
'***

'*** fil1
    Dim testObj1 As New Textbox
    With textObj1
        blalblabl
    End With
'***

'*** fil2
    Dim testObj2 As New Textbox
    With textObj2
        blalblabl
    End With
   
    Dim testObj3 As New Checkbox
    With textObj3
        blalblabl
    End With
'***

Dvs. noget, der i klassisk asp, ville svare til :
'*** default.aspx.vb
Partial Class _Default
  Inherits System.Web.UI.Page
  Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
      <!--#include file="fil2"-->
  End Sub
End Class
'***

De inkluderede filer vil kun skulle indeholder objektdeklarationer - intet andet. Men de resulterende objekter skal kunne bibeholde viewstate, så de skal deklareres i page.init.
Jeg har forsøgt lidt med Usercontrols, men det spiller ikke rigtig for mig.

Applikationen virker som den er nu, hvor "fil1" og "fil2" eksisterer i hver sin .aspx, men målet er at kunne have een basis-aspx-fil og een basis-aspx.vb-fil
og så lade de enkelte sider i applikationen hente objektdeklaration "eksternt".

Så: Kan man overhovedet gøre det her?
Avatar billede neoman Novice
28. oktober 2007 - 11:26 #1
Hvad er det der ikke spiller med usercontrols ? Det er mig bekendt præcist dette de bruges til, at man at run time beslutter hvilken control skal loades, og denne kan så indeholde alt det man har lyst til.
Avatar billede neoman Novice
28. oktober 2007 - 11:37 #2
Hvis det kun er lidt kode (og ikke andet) som skal køres, så kan man  lægge koden ind i nogle metoder i App_Code og kalde dem efter behov.
Avatar billede madmital Nybegynder
28. oktober 2007 - 13:11 #3
Joh tak :)

Jeg syntes også Usercontrols lugtede af det rigtige, men som sagt kan jeg ikke rigtig få det til at køre.

Jeg kan godt lave en Usercontrol ascx med mine deklarationer i, så fint. Og jeg kan også eksekvere koden på det rigtige, men kan dog kun få det til at virke at oprette min Usercontrol manuelt.

Det her virker:

' ***
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" theme="customMenu" ValidateRequest="false" ResponseEncoding="UTF-8" %>

<%@ Register TagPrefix="mitaltext" Src="~/WebUserControl.ascx" TagName="mmm"  %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<body runat="server" >
<script runat="server">
    Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
    End Sub
</script>
<form id="form1" runat="server" ENCTYPE="Multipart/Form-Data">

<mitaltext:mmm runat="server" />
' ***

Men jeg ville gerne have det her...som så ikke virker (?):
' ***
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" theme="customMenu" ValidateRequest="false" ResponseEncoding="UTF-8" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<body runat="server" >
<script runat="server">
    Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
        Dim testUC As New UserControl
        testUC.LoadControl("WebUserControl.ascx")
        Controls.Add(testUC)
    End Sub
</script>
' ***


WebUserControl.ascx ser fx. sårn her ud:
' ***
<%@ Control Language="VB" ClassName="WebUserControl" %>
<%@ Import Namespace="DNM" %> <%@ Import Namespace="DNM.engine" %>
<script runat="server">
    Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs)
        dnm2.clearObjectCollection()
     
        tableName = "test"
        canCreate = False

        Dim obj1_t As New dnmCheck("yesno", "mital", True, False, "", False, True, False)
       
        Dim dnm2PageSelect As New dnmDropDownList("selectvalopt", "vm1", True, False, "1", False, False, False)
        With dnm2PageSelect
            .Displayfield = "stext"
        End With
    End Sub
</script>
' ***
Avatar billede neoman Novice
28. oktober 2007 - 13:50 #4
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" theme="customMenu" ValidateRequest="false" ResponseEncoding="UTF-8" %>

<%@ Register TagPrefix="mitaltext" Src="~/WebUserControl.ascx" TagName="mmm"  %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<body runat="server" >
<script runat="server">
    Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
    End Sub
</script>
<form id="form1" runat="server" ENCTYPE="Multipart/Form-Data">

<mitaltext:mmm runat="server" />
' ***

1. fjern <mitaltext:mmm runat="server" />
men bevar 
<%@ Register TagPrefix="mitaltext" Src="~/WebUserControl.ascx" TagName="mmm"  %> der hvor den er nu

2. I page load eller page init skriv:

  Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
        Dim testUC As Control=LoadControl("WebUserControl.ascx")
   
        PlaceHolder1.Controls.Add(testUC)' hvor du så har lagt en placeholder et setd i din aspx
    End Sub


I øvrigt: "virker ikke" viker ikke - skriv altid:
a). Hvad du ønsker og
b) hvordan systemet reagerer på koden, ellers er det svært at gætte)
Avatar billede neoman Novice
28. oktober 2007 - 14:04 #5
Jeg kan ikke helt se hvorfor user controller skulle blandes ind i dette her, så længe du kun har nogle kald til noget kode inde i dem.

så er der vel ingen grund til at blande user controls ind i tingene ? Koden kan jo ligge i App_Code folderen og blive kaldt. Din dnm-ting laver tydelig visnogle kontroller, og de skal blot placeres på siden i en container. Navneet på containeren kan du altid give som en parameter i en metode, hvor metoden så kalder dine dnm-funktioner.

Selve metoden kan så ligge i samme vb fil eller en klasse fil i asp_code, og i sidste fald formentligt med lidt Imports af de forskellige relevante name spaces.
Avatar billede madmital Nybegynder
28. oktober 2007 - 16:22 #6
Du har ret ang. "virker ikke"....undskyld.
"Virker ikke" i den sammenhæng betyder, at Usercontrol'en aldrig blive eksekveret.

Hele applikationene er noget CMS-lignende halløj, hvor en (lad os kalde ham) semi-administrator, kan oprette nye admin-sider med bestemte controls efter behov.
Således er en ny admin-side faktisk kun en række deklarationer, fx:
Dim etellerandet As New dnmText osv.
mens koden, der så generer controls og gemmer data osv ligger som nogle fælles classes.

I den nuværende version har hver admin-side sin egen .aspx-fil, som indeholder både noget html, nogle faste controls og de custom declarations.
Mit mål er at skille tingene ad, så de custom objektdeklarationer får sine helt egne filer eller classes som den fælles kode kan kalde og anvende.  Men jeg skal have bibeholdt funktionaliteten i, at en given person bare kan deklarere nogle objekter så bare glemme resten.
Avatar billede neoman Novice
28. oktober 2007 - 19:30 #7
Aspx
----------------
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="TestDyn.aspx.vb" Inherits="TestDyn" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
    </div>
    </form>
</body>
</html>

code behind
------------------
Partial Class TestDyn
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        DynControls.MyControl1(PlaceHolder1)
    End Sub
End Class

i App_Code
-----------
Imports Microsoft.VisualBasic

Public Class DynControls
    Public Shared Sub MyControl1(ByVal myPlaceholder As PlaceHolder)
        Dim myTextBox As New TextBox
        myTextBox.Text = "37"
        myPlaceholder.Controls.Add(myTextBox)
    End Sub
End Class

mon ikke noget i ovenstående stil ?
Avatar billede neoman Novice
28. oktober 2007 - 19:52 #8
eller faktisk bedre med
Partial Class TestDyn
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim mycontrols As New DynControls
        mycontrols.MyControl1(PlaceHolder1)
    End Sub
End Class

og

Imports Microsoft.VisualBasic
Public Class DynControls
    Public Sub MyControl1(ByVal myPlaceholder As PlaceHolder)
        Dim myTextBox As New TextBox
        myTextBox.Text = "37"
        myPlaceholder.Controls.Add(myTextBox)
    End Sub
End Class
Avatar billede ieconfig Nybegynder
28. oktober 2007 - 23:24 #9
Grunden til at du tror at UserKontrollen ikke bliver eksekveret er at dens Init, Load osv metoder kører EFTER aspx siden (Page nedarvede).

F.eks

public WebUserControl() { Test = "I ctor!"; }

protected void Page_Load(object sender, EventArgs e)
{ Test = "I Page_Load!"; }

Hvis du aflæser Test i din Page_Load i din aspx fil vil du få "I ctor!", da Page_Load ikke er afviklet i UserKontrollen endnu..
Avatar billede madmital Nybegynder
29. oktober 2007 - 18:36 #10
neoman:
Naah...det ville bare give mig endnu flere filer...

Så ville jeg for hver enkelt side skulle have både en aspx og en CodeFile, plus at App_Code dir'et skulle indblandes. Jeg precompiler "motor"-delen af applikationen, og skulle gerne hold App_Code ude af billedet.

Men jeg kom til at tænke på om jeg kunne opnå det ved at bruge en master page...
Jeg er lidt rusten i Master pages, men både den og "included" aspx'er har vel deres egen Init-sektion (?). Så der bare eksekveringsrækkefølgen...
Må lige lave en test når tiden tillader det.


ieconfig:
Jeg mener også jeg konstaterede rækkefølge i eksekveringen af page/usercontrol (brekpoints/debug er nu en god ting), og jeg kunne også få tingene til at spille....bare ikke med dynamisk variation af hvilken usercontrol der bliver loaded.
Avatar billede madmital Nybegynder
29. oktober 2007 - 19:18 #11
Hmmm...tiden tillod det lige med det samme :)

Men en masterpage kan jeg faktisk opnå det jeg gerne vil:

Master page:
Partial Class dnmMaster
    Inherits System.Web.UI.MasterPage

    Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
        ' *** Diverse indledende øvelser/validering
    End Sub

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        ' *** Kald til main function i "motor"-class.
    End Sub
End Class

ASPX:
<%@ Page Language="VB" MasterPageFile="~/dnmMaster.master" Title="" %>
<asp:Content ID="Content1" ContentPlaceHolderID="contentPlaceHolder1" Runat="Server">
<script runat="server">
    Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
        Dim pageDate As New dnmDate("date", "Dato", True, False, "", False, True, False)
        ' *** flere objekt-deklarationer
    End Sub
</script>
</asp:Content>

Således bliver masterpage'ens Init kaldt først, dernæst aspx'ens Init, og dernæst masterpage'ens Load.
Så kan jeg lægge alle de fælles routiner i "motor"-class'es, nøjes med een fælles Init, der forbereder "motor'en", og så x-antal aspx'er med objektdeklarationer og kun et par linjer obligatorisk sovs (som folk vel nok kan lære, at lade være i fred :) ).

Ovenstående virker som løsning på det jeg gerne ville opnå.

Tak for sparringen, neoman.
(...du er velkommen til at lægge et svar.)
Avatar billede neoman Novice
29. oktober 2007 - 19:26 #12
pyt med points - hvis dit sjov virker så er det godt nok, jeg fattede vist aldrig helt hvad du ville. Bemærk dog at init er lidt sjov, da både init og unload kører indefra og udefter, mens alle andre events kaldes omvendt. Og - MasterPage er child af page, underligt nok, så PageLoad for aspx siden kører først og derpå masterens page load.
Avatar billede madmital Nybegynder
29. oktober 2007 - 19:36 #13
Nej...det kan godt være man skal være lidt miljøskadet for at følge den.
Men nogle gange får man idéer af bare at få lov at fortælle om det :)

Hmm...jeg var ikke klar over rækkefølgen for PageLoad. Dén er noteret. Tak.
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