Avatar billede forceprogrammer Nybegynder
30. januar 2005 - 23:05 Der er 20 kommentarer

eventhåndtering af dynamisk generede checkbokse

Jeg har en tabel der bliver genereret dynamisk i min codebehind.
En af kolonnerne i denne tabel hedder slet og indeholde en søjle af checkboxes.
Det er meningen at når brugeren trykker på en sådan checkbox skal en eventhandler i min codebehind kaldes således at jeg kan slette den pågældende række.

Eventhandleren bliver ikke kaldt når en checkboks bliver trykket...Jeg forstår ikke hvorfor.
Der bliver lavet postback som der skal, men eventhandleren bliver altså ikke handlet.

Et ekstra spg. til dette er hvordan jeg får denne checkboks til at sende information om rækken den er en del af således at jeg ved hvilken række jeg skal slette fra tabellen. Altså det man i gamle dage ville gøre vha. querystrengen. -> &rowID=23 man vidste altså så at det var rowId 23 der skulle manipuleres.

Jeg er ikke helt med på hvordan jeg gør det i dotnet.

Den kode jeg har lavet er følgende:(Hvis jeg er uforståelig så sig det og jeg uddyber meget gerne.)

private void btnAddLines_Click(object sender, EventArgs e)
        {
            try
            {
               
                System.Collections.ArrayList orderLines=
                    bll.addOrderLines((System.Collections.ArrayList)Session["bestillingsLinier"],
                    cmbAutomater.Items,cmbYdelser.Items,txtAutomat.Text);

               
                System.Web.UI.WebControls.TableRow row;
               
                row=new System.Web.UI.WebControls.TableRow();
                row=addHeaderCell(row,"#");
                row=addHeaderCell(row,"Serienummer");
                row=addHeaderCell(row,"Navn");
                row=addHeaderCell(row,"Elektronik");
                row=addHeaderCell(row,"Fabrikat");
                row=addHeaderCell(row,"Kabinet");
                row=addHeaderCell(row,"Programmel");
                row=addHeaderCell(row,"Ydelse");
                row=addHeaderCell(row,"slet");
                tblBestillinger.Rows.Add(row);
                int ctr=1;
                foreach(BLL.BusinessEntities.Bestillingslinie bl in orderLines)
                {
                    row=new System.Web.UI.WebControls.TableRow();
                    row=addCell(row,Convert.ToString(ctr++));
                    row=addCell(row,bl.AUT_SER_NR);
                    row=addCell(row,bl.AUT_NAVN);
                    row=addCell(row,bl.ELKTR_BETEGN);
                    row=addCell(row,bl.FABR_BETEGN);
                    row=addCell(row,bl.KAB_BETEGN);
                    row=addCell(row,bl.PROG_VERS);
                    row=addCell(row,bl.YDELSE_NAVN);
                    System.Web.UI.WebControls.TableCell tc=new System.Web.UI.WebControls.TableCell();
                   
                    System.Web.UI.WebControls.CheckBox chk=new System.Web.UI.WebControls.CheckBox();
                    chk.AutoPostBack=true;
                   
                    chk.CheckedChanged+=new EventHandler(chk_CheckedChanged);
                    tc.Controls.Add(chk);
                    row.Cells.Add(tc);
                    tblBestillinger.Rows.Add(row);
                }
            }
            catch(Exception exc)
            {
                Response.Write(exc.Message);
                Response.Write("<br>");
                Response.Write(exc.StackTrace);
            }

        }

        private System.Web.UI.WebControls.TableRow addHeaderCell(System.Web.UI.WebControls.TableRow row,string innerHtml)
        {
            System.Web.UI.WebControls.TableHeaderCell thc=new System.Web.UI.WebControls.TableHeaderCell();
            thc.Text=innerHtml;
            row.Cells.Add(thc);
            return row;
        }
        private System.Web.UI.WebControls.TableRow addCell(System.Web.UI.WebControls.TableRow row,string innerHtml)
        {
            System.Web.UI.WebControls.TableCell tc=new System.Web.UI.WebControls.TableCell();
            tc.Text=innerHtml;
            row.Cells.Add(tc);
            return row;
        }

        private void InitializeComponent()
        {   
            this.Load += new System.EventHandler(this.Page_Load);
            btnAddLines.Click+=new EventHandler(btnAddLines_Click);
            cmbSted.SelectedIndexChanged+=new EventHandler(cmbSted_SelectedIndexChanged);
            btnMakeOrder.Click+=new EventHandler(btnMakeOrder_Click);
        }

        private void chk_CheckedChanged(object sender, EventArgs e)
        {
            Response.Write("checked");//Denne funktion bliver ikke kaldt
        }
Avatar billede thomashove Nybegynder
31. januar 2005 - 11:39 #1
ved postback, husker du da at loade de dynamiske controls igen ?
Avatar billede thomashove Nybegynder
31. januar 2005 - 11:51 #2
flg. simple eksempel virker fint (skrevet i VB - men kan sikkert bruges som inspiration)

Dim ddl As DropDownList = New System.Web.UI.WebControls.DropDownList

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'Put user code to initialize the page here

        ddl.ID = "MyDropdownList"
        ddl.AutoPostBack = True
        ddl.Items.Add("one")
        ddl.Items.Add("two")
        ddl.Items.Add("Three")
        ddl.EnableViewState = True
        AddHandler ddl.SelectedIndexChanged, AddressOf ddl_SelectedIndexChanged
        PlaceHolder1.Controls.Add(ddl)
    End Sub

    Private Sub ddl_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Label1.Text = "du valgte item : " + ddl.SelectedValue.ToString
    End Sub
Avatar billede forceprogrammer Nybegynder
31. januar 2005 - 11:57 #3
super...det var det jeg havde glemt :)
piinligt hva hehe...

Må jeg spørge om en ting til?

Hvordan får jeg den så til at sende information med om rækken den tilhører. Altså checkboksen.
Således at jeg kan i eventhandleren kode:

fjern linien som er repræsenteret af den aktuelle checkboks.
Avatar billede forceprogrammer Nybegynder
31. januar 2005 - 12:23 #4
tænkte på at sende info med sammen med eventargs.

Men hvordan gør jeg det?
Avatar billede thomashove Nybegynder
31. januar 2005 - 13:17 #5
der er flere måder at løse det på. En af dem kunne være at lave en collection a checkboxes og iterere igennem denne i eventhandleren... F.eks.

Dim chk(1) As CheckBox

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'Put user code to initialize the page here

        Dim i As Integer
        For i = 0 To 1
            chk(i) = New System.Web.UI.WebControls.CheckBox
            chk(i).AutoPostBack = True
            chk(i).Text = "Checkbox:" + i.ToString
            chk(i).ID = i.ToString
            AddHandler chk(i).CheckedChanged, AddressOf chk_CheckedChanged
            PlaceHolder1.Controls.Add(chk(i))
        Next
    End Sub

    Private Sub chk_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim i
        For i = 0 To chk.Length - 1
            If chk(i).Checked Then
                Label1.Text = "du valgte checkbox : " + chk(i).ID
            End If
        Next
    End Sub
Avatar billede thomashove Nybegynder
31. januar 2005 - 13:18 #6
du kan så via checkboxens ID se hvilken række der er tale om
Avatar billede -psycho- Nybegynder
31. januar 2005 - 14:13 #7
Ok værsgo her er noget man bruger nu et datagrid. Så håber du kan bruge det alligevel.

private void Page_Load(object sender, System.EventArgs e)
{
  ArrayList _List = (ArrayList)Session["List"];

  DataTable _Table = new DataTable();
  _Table.Columns.AddRange(new DataColumn[] {new DataColumn("#"), new DataColumn("col1"), new DataColumn("col2")});

  DataRow _Row;

  foreach(Object[] _Obj in _List)
  {   
    _Row = _Table.NewRow();
    _Row.ItemArray = _Obj;
    _Table.Rows.Add(_Row);
  }

  BoundColumn _ColID = new BoundColumn();
  _ColID.HeaderText = "#";
  _ColID.DataField = "#";
       
  BoundColumn _Col1 = new BoundColumn();
  _Col1.HeaderText = "col1";
  _Col1.DataField = "col1";

  BoundColumn _Col2 = new BoundColumn();
  _Col2.HeaderText = "col2";
  _Col2.DataField = "col2";

  TemplateColumn _TC = new TemplateColumn();
  CheckBoxTemplate _ChkTemp = new CheckBoxTemplate();
  _ChkTemp.CheckedChanged += new EventHandler(slet);
  _TC.ItemTemplate = _ChkTemp;

  DataGrid.Columns.Add(_ColID);
  DataGrid.Columns.Add(_Col1);
  DataGrid.Columns.Add(_Col2);
  DataGrid.Columns.Add(_TC);
           
  DataGrid.DataSource = _Table;
  DataBind();
}

private void slet(object sender, EventArgs e)
{
  CheckBox chk = (CheckBox)sender;
  DataGridItem item = (DataGridItem)chk.NamingContainer;

// item.Cells[0].Text;  <-- teksten fra # cellen
}

/*****************************************************************/

internal class CheckBoxTemplate : ITemplate
{
  void ITemplate.InstantiateIn(Control container)
  {
    CheckBox chk = new CheckBox();
   
    chk.AutoPostBack = true;
    chk.Checked = false;

    chk.CheckedChanged += new EventHandler(this.OnCheckChanged);
    container.Controls.Add(chk);
  }

  public event EventHandler CheckedChanged;

  private void OnCheckChanged(object sender, EventArgs e)
  {
    if (CheckedChanged != null)
    {
      CheckedChanged(sender, e);
    }
  }
}
Avatar billede forceprogrammer Nybegynder
31. januar 2005 - 14:32 #8
hmm ja...det ser ud som om det er noget jeg kan bruge....men jeg kan ikke få det til at virke helt.

Det ser ud som om det kræver 2 tryk på checkboksen før den bliver slettet.
Det må have noget at gøre med at checkboksene ikke bliver oprettet på det rigtige tidspunkt....Jeg skal nok give flere point for jeg ved godt det går ud over spørgsmålets kanter. Men hvis i gad lige at prøve at kigge på hvad der evt. går galt.

Nu viser jeg hele code-behind for at give en bedre sammenhæng.

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace vegasonline.UIL
{
    /// <summary>
    /// Summary description for StedBestilling.
    /// </summary>
    public class StedBestilling : GenericWebPage
    {
        protected ForceUI.web.ForceDropDownBox cmbSted;
        protected ForceUI.web.ForceListBox cmbYdelser;
        protected ForceUI.web.ForceListBox cmbAutomater;
        protected ForceUI.web.ForceTextbox txtOenskeDato;
        protected ForceUI.web.ForceTextbox txtAutomat;
        protected System.Web.UI.WebControls.Table tblBestillinger;
        protected System.Web.UI.WebControls.DataGrid datBestillinger;
        protected System.Web.UI.WebControls.Button btnAddLines;
        protected System.Web.UI.WebControls.Button btnMakeOrder;
        protected System.Web.UI.WebControls.Button btnDeleteLines;
       
        protected System.Web.UI.WebControls.PlaceHolder plcMakeOrders;
       
        private void Page_Load(object sender, System.EventArgs e)
        {
           
            if(!IsPostBack)
            {
                bindDropDownBox(cmbSted,bll.getStedList(),"VAERDI","MULIG");
                cmbSted.AutoPostBack=true;
                plcMakeOrders.Visible=false;
            }
            else
            {
                tblBestillinger.Attributes.Add("Border","2");
                tblBestillinger.CellPadding=3;
                tblBestillinger.CellSpacing=0;
                if(Session["bestillingsLinier"]==null)
                    Session["bestillingsLinier"]=new System.Collections.ArrayList();
                updateLineTable((System.Collections.ArrayList)Session["bestillingsLinier"]);
            }
           
           
        }

        #region Web Form Designer generated code
        override protected void OnInit(EventArgs e)
        {
            //
            // CODEGEN: This call is required by the ASP.NET Web Form Designer.
            //
            InitializeComponent();
            base.OnInit(e);
        }
       
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {   
            this.Load += new System.EventHandler(this.Page_Load);
            btnAddLines.Click+=new EventHandler(btnAddLines_Click);
            cmbSted.SelectedIndexChanged+=new EventHandler(cmbSted_SelectedIndexChanged);
            btnMakeOrder.Click+=new EventHandler(btnMakeOrder_Click);
        }
        #endregion
       
        private System.Web.UI.WebControls.TableRow addHeaderCell(System.Web.UI.WebControls.TableRow row,string innerHtml)
        {
            System.Web.UI.WebControls.TableHeaderCell thc=new System.Web.UI.WebControls.TableHeaderCell();
            thc.Text=innerHtml;
            row.Cells.Add(thc);
            return row;
        }
        private System.Web.UI.WebControls.TableRow addCell(System.Web.UI.WebControls.TableRow row,string innerHtml)
        {
            System.Web.UI.WebControls.TableCell tc=new System.Web.UI.WebControls.TableCell();
            tc.Text=innerHtml;
            row.Cells.Add(tc);
           
            return row;
        }

        private void updateLineTable(System.Collections.ArrayList orderLines)
        {
            tblBestillinger.Rows.Clear();
            try
            {
               
                System.Web.UI.WebControls.TableRow row;
                System.Web.UI.WebControls.TableCell tc;

                row=new System.Web.UI.WebControls.TableRow();
                row=addHeaderCell(row,"#");
                row=addHeaderCell(row,"Serienummer");
                row=addHeaderCell(row,"Navn");
                row=addHeaderCell(row,"Elektronik");
                row=addHeaderCell(row,"Fabrikat");
                row=addHeaderCell(row,"Kabinet");
                row=addHeaderCell(row,"Programmel");
                row=addHeaderCell(row,"Ydelse");
                row=addHeaderCell(row,"slet");
                tblBestillinger.Rows.Add(row);
                int ctr=1;
                foreach(BLL.BusinessEntities.Bestillingslinie bl in orderLines)
                {
                    row=new System.Web.UI.WebControls.TableRow();
                    row=addCell(row,Convert.ToString(ctr++));
                    row=addCell(row,bl.AUT_SER_NR);
                    row=addCell(row,bl.AUT_NAVN);
                    row=addCell(row,bl.ELKTR_BETEGN);
                    row=addCell(row,bl.FABR_BETEGN);
                    row=addCell(row,bl.KAB_BETEGN);
                    row=addCell(row,bl.PROG_VERS);
                    row=addCell(row,bl.YDELSE_NAVN);
                    tc=new System.Web.UI.WebControls.TableCell();
                   
                    System.Web.UI.WebControls.CheckBox chk=new System.Web.UI.WebControls.CheckBox();
                    chk.AutoPostBack=true;
                   
                    chk.CheckedChanged+=new EventHandler(chk_CheckedChanged);
                    chk.Attributes.Add("value",bl.AUT_SER_NR+"$"+bl.YDELSENR);
                    tc.Controls.Add(chk);
                    row.Cells.Add(tc);
                    tblBestillinger.Rows.Add(row);
                }
                /*
                row=new System.Web.UI.WebControls.TableRow();
                btnDeleteLines=new System.Web.UI.WebControls.Button();
                btnDeleteLines.Text="Fjern valgte";
                btnDeleteLines.Click+=new EventHandler(btnDeleteLines_Click);
                tc=new System.Web.UI.WebControls.TableCell();
                tc.ColumnSpan=9;
                tc.HorizontalAlign=System.Web.UI.WebControls.HorizontalAlign.Right;
                tc.Controls.Add(btnDeleteLines);
                row.Cells.Add(tc);
                tblBestillinger.Rows.Add(row);
                */
               
            }
            catch(Exception exc)
            {
                Response.Write(exc.Message);
                Response.Write("<br>");
                Response.Write(exc.StackTrace);
            }
        }

        private void btnAddLines_Click(object sender, EventArgs e)
        {
            Session["bestillingsLinier"]=
                bll.addOrderLines((System.Collections.ArrayList)Session["bestillingsLinier"],
                cmbAutomater.Items,cmbYdelser.Items,txtAutomat.Text);
            updateLineTable((System.Collections.ArrayList)Session["bestillingsLinier"]);
            //Tom eventhandler da bestillingslinierne bliver opdateret i postback i page_load
        }

        private void cmbSted_SelectedIndexChanged(object sender, EventArgs e)
        {
            bindDropDownBox(cmbAutomater,bll.getAutNavnListPerSted(Convert.ToInt32(cmbSted.SelectedValue)),"VAERDI","MULIG");
            bindDropDownBox(cmbYdelser,bll.getYdelseList(),"VAERDI","MULIG");
            cmbYdelser.SelectionMode=System.Web.UI.WebControls.ListSelectionMode.Multiple;
            cmbAutomater.SelectionMode=System.Web.UI.WebControls.ListSelectionMode.Multiple;
            cmbYdelser.Rows=10;
            cmbAutomater.Rows=10;
            plcMakeOrders.Visible=true;
            Session["bestillingsLinier"]=new System.Collections.ArrayList();
           
        }

        private void btnMakeOrder_Click(object sender, EventArgs e)
        {
            bll.createOrder((System.Collections.Hashtable)Session["bestillingsLinier"],txtOenskeDato.Text);
            Response.Write("Order created");
        }

        private void chk_CheckedChanged(object sender, EventArgs e)
        {
            System.Web.UI.WebControls.CheckBox chk=(System.Web.UI.WebControls.CheckBox)sender;
            Session["bestillingsLinier"]=bll.moveRow((System.Collections.ArrayList)Session["bestillingsLinier"],chk.Attributes["value"]);
            updateLineTable((System.Collections.ArrayList)Session["bestillingsLinier"]);
        }

    }
}
/******************************************************/
bll klassen som der bliver kaldt forskellige steder

        public System.Collections.ArrayList addOrderLines(System.Collections.ArrayList existingOrderLines,
            System.Web.UI.WebControls.ListItemCollection automater,
            System.Web.UI.WebControls.ListItemCollection ydelser,string newAutomatSerial)
        {
       
            foreach(System.Web.UI.WebControls.ListItem lstAutomat in automater)
            {
                foreach(System.Web.UI.WebControls.ListItem lstService in ydelser)
                {
                    if(lstAutomat.Selected)
                    {
                        if(lstService.Selected)
                        {
                           
                            //Eventuelle ulovlige automat/ydelse kombinationer kan laves her
                            BusinessEntities.Bestillingslinie bl=new BusinessEntities.Bestillingslinie(
                                lstAutomat.Value,
                                Convert.ToInt32(lstService.Value),this);
                            if(!existingOrderLines.Contains(bl))
                            {
                                bl.populateProperties();
                                existingOrderLines.Add(bl);
                            }
                        }
                    }
                }
            }
           
            if(newAutomatSerial!=null)
            {
                if(!newAutomatSerial.Equals(""))
                {
                    foreach(System.Web.UI.WebControls.ListItem lstService in ydelser)
                    {
                        if(lstService.Selected)
                        {
                            //Eventuelle ulovlige automat/ydelse kombinationer kan laves her
                            BusinessEntities.Bestillingslinie bl=new BusinessEntities.Bestillingslinie(
                                newAutomatSerial,
                                Convert.ToInt32(lstService.Value),this);
                            if(!existingOrderLines.Contains(bl))
                            {
                                bl.populateProperties();
                                existingOrderLines.Add(bl);
                            }
                        }
                    }
                }
            }

            return existingOrderLines;
        }
        public System.Collections.ArrayList moveRow(System.Collections.ArrayList orders,string orderId)
        {
            System.Collections.ArrayList ordersNotDeleted=new System.Collections.ArrayList();
            string[] theSplit=orderId.Split(new char[]{'$'});
            foreach(BLL.BusinessEntities.Bestillingslinie bl in orders)
            {
                if(bl.AUT_SER_NR.Equals(theSplit[0]) && bl.YDELSENR==Convert.ToInt32(theSplit[1]))
                    continue;
                else
                    ordersNotDeleted.Add(bl);
            }
            return ordersNotDeleted;
        }
Avatar billede forceprogrammer Nybegynder
31. januar 2005 - 14:34 #9
Forresten jeg valgte løsningen at tilføje en attribute som jeg bruger til at identificere checkboksen.
Jeg ved ikke om det er en holdbar løsning...men det virker vidst :)
hæhæ
Avatar billede forceprogrammer Nybegynder
31. januar 2005 - 14:47 #10
Det jeg ikke fatter er at første gang sletboksen trykkes bliver rækken fjernet første gang.
Men resten af rækkerne kræver 2 tryk, altså to serverroundtrips før denne bliver slettet.
Jeg forstår det simpelthen ikke.
Avatar billede -psycho- Nybegynder
31. januar 2005 - 14:59 #11
Hvis det var til mig med det det krævede 2 click for at få den fjernet så ja det går den du er nød til at opdatere datagrided.

Flyt
DataTable _Table = new DataTable();
DataRow _Row;

så de er globale.


private void slet(object sender, EventArgs e)
{
  CheckBox chk = (CheckBox)sender;
  DataGridItem item = (DataGridItem)chk.NamingContainer;

  // item.Cells[0].Text Teksten fra # cellen

  ArrayList _List = (ArrayList)Session["List"];

  _List.RemoveAt(item.ItemIndex);

  _Table.Clear();

  foreach(Object[] _Obj in _List)
  {   
    _Row = _Table.NewRow();
    _Row.ItemArray = _Obj;
    _Table.Rows.Add(_Row);
  }

  Session["List"] = _List;

  DataGrid.DataSource = _Table;
  DataBind();
}
Avatar billede forceprogrammer Nybegynder
31. januar 2005 - 15:16 #12
Men jeg bruger ikke datagrid.
Jeg bruger en tabel som jeg har postet deroppe....Der er samme problemstilling eller hvordan?
Avatar billede -psycho- Nybegynder
31. januar 2005 - 15:24 #13
Det at den kræver 2 roundtrips kunne tyde på at din tabel ikke bliver opdateret når du sletter men først næste gang siden loader.

Sidder og kigger din kode igennem. Jeg ville nu foreslå at bruge et datagrid men det er selvfølgelig op til dig. Men kan ikke lige se hvorfor det virker første gang men så ikke mere.
Avatar billede forceprogrammer Nybegynder
31. januar 2005 - 15:28 #14
Det er super.
Jeg værdsætter din hjælp :)
Hvis det viser sig at være helt umulig kode må du lige sige til :)
Avatar billede -psycho- Nybegynder
31. januar 2005 - 16:00 #15
Kan du sq ikke se hvad der er galt.

prøv lige.

private void chk_CheckedChanged(object sender, EventArgs e)
{
  System.Web.UI.WebControls.CheckBox chk=(System.Web.UI.WebControls.CheckBox)sender;
   
  ArrayList oldlist = (ArrayList)Session["bestillingsLinier"];

  Session["bestillingsLinier"]=bll.moveRow((System.Collections.ArrayList)Session["bestillingsLinier"],chk.Attributes["value"]);
           
  ArrayList newlist = (ArrayList)Session["bestillingsLinier"];

  oldlist.Equals(newlist); //<-- prøv lige at skrive den ud den skulle gerne være false altid

  updateLineTable((System.Collections.ArrayList)Session["bestillingsLinier"]);
}
Avatar billede forceprogrammer Nybegynder
31. januar 2005 - 16:15 #16
Ja, den er rigtig nok false hver gang.

Men selve eventhandleren bliver kun kaldt hver anden gang.

Det er lidt mystisk
Avatar billede forceprogrammer Nybegynder
31. januar 2005 - 16:15 #17
Så altså der bliver kun fjernet orderlines på hvert andet klik...hmmm
Avatar billede -psycho- Nybegynder
31. januar 2005 - 16:25 #18
hmm, kun hver anden gang det giver ikke lige frem nogen mening men så ved vi da det.
Avatar billede -psycho- Nybegynder
31. januar 2005 - 16:59 #19
Tror jeg er nød til at melde pas på nuværende tidspunkt kan ikke se hvorfor den gør som den gør.

Er sikkert et eller andet latterligt som er lige foran en :). Men som der er nu virker det som om at evented på checkboxen kun bliver sat til når updateLineTable bliver kaldt fra page_load men ikke fra chk_CheckedChanged.
Avatar billede stinejh1980 Nybegynder
20. februar 2007 - 08:26 #20
Thomashove >>

Kan du hjælpe mig?
Mit spsm minder meget om dette?

http://www.eksperten.dk/spm/763464
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