Domanda

Questo è il mio primo post! Sono abbastanza disperato quindi sto andando al di là della mia googling standard. Credo che questa è una domanda avanzata o a livello di esperti NET.

Il problema è che io ho costruito un'applicazione web .NET che deve essere in grado di inserire controlli utente in modo dinamico nel bel mezzo di una lista. Sono abbastanza confortevole con controlli dinamici così tanto tempo hanno solo bisogno di essere aggiunto alla fine della lista (es: ho familiarità con articoli come questo: http://msdn.microsoft.com/en-us/library/ms972976.aspx ). Tuttavia, se ho bisogno di aggiungere un UserControl al fronte di una raccolta Controls o da qualche parte nel mezzo che sto praticamente perso in quanto l'UniqueID del controllo è gettato fuori.

Come un esempio semplificato, diciamo che ho un pannello a cui sto aggiungendo una lista di controlli utente chiamato MyControl.ascx. Ho anche qualche evento che può essere licenziato nella pagina per che ha la necessità di inserire dinamicamente un MyControl.ascx nell'indice specificato dell'insieme Controls del pannello. Ho anche uno o più eventi in MyControl.ascx a cui ho bisogno di iscriversi. Ciò significa che i controlli devono essere caricati prima degli eventi di questi controlli avrebbero sparato, altrimenti non spareranno. Se non sai a cosa mi riferisco poi mi sia formulata la questione male o questa domanda potrebbe essere troppo difficile per voi :)

Di seguito è un po 'C # pseudocodice per dimostrare il problema. Il problema è che il metodo Controls.AddAt (indice, controllo) non regola i valori uniqueID dei controlli di conseguenza. Ad esempio, considerare i seguenti controlli in una collezione Controls:

Sia Sto scrivendo del codice che dipende direttamente dalla UniqueID o no, .NET utilizza indirettamente l'UniqueID per collegare tra loro gli eventi che sono stati licenziati sul postback precedente con i comandi vengono caricati sul nuovo postback. Prendendo il mio esempio precedente:

Il Page Load (Page.IsPostback == false) iniziale

<table>
  <tr>
    <td width='100'>Control index</td>
    <td width='75'>UniqueID</td>
    <td>Value</td>
  </tr>
  <tr>
    <td>0</td>
    <td>ctl00</td>
    <td>value1</td>
  </tr>
  <tr>
    <td>1</td>
    <td>ctl01</td>
    <td>value2</td>
  </tr>
  <tr>
    <td>2</td>
    <td>ctl02</td>
    <td>value3</td>
  </tr>
</table>

Dopo un postback (Page.IsPostback == false) da qualche altro controllo che vuole inserire il controllo in corrispondenza dell'indice 0:

Se faccio un Controls.AddAt(0, newControl) poi Controls sembra qualcosa di simile:

<table>
  <tr>
    <td width='100'>Control index</td>
    <td width='75'>UniqueID</td>
    <td>Value</td>
  </tr>
  <tr>
    <td>0</td>
    <td>ctl03</td>
    <td>value0  <== the controls' unique IDs do not shift!</td>
  </tr>
  <tr>
    <td>1</td>
    <td>ctl00</td>
    <td>value1</td>
  </tr>
  <tr>
    <td>2</td>
    <td>ctl01</td>
    <td>value2</td>
  </tr>
  <tr>
    <td>3</td>
    <td>ctl02</td>
    <td>value3</td>
  </tr>
</table>

Quindi, se dovessi fare clic su un LinkButton nel controllo con Value == Valore0 e UniqueID == ctl03, i controlli sarebbero essere ordinato come il seguente su post-back e le UniqueIDs non sarebbero nell'ordine che voglio. Questo farà sì che l'evento click di allegare al controllo sbagliato:

<table>
  <tr>
    <td width='100'>Control index</td>
    <td width='75'>UniqueID</td>
    <td>Value</td>
  </tr>
  <tr>
    <td>0</td>
    <td>ctl00</td>
    <td>value0  <== the control i wanted to throw the event</td>
  </tr>
  <tr>
    <td>1</td>
    <td>ctl01</td>
    <td>value1</td>
  </tr>
  <tr>
    <td>2</td>
    <td>ctl02</td>
    <td>value2</td>
  </tr>
  <tr>
    <td>3</td>
    <td>ctl03</td>
    <td>value3  <== the actual control to which the event is attached</td>
  </tr>
</table>

Se io non ho dovuto gestire gli eventi da questi controlli dinamici questo probabilmente non sarebbe un problema. Ecco il mio codice:

// on init i just need to pull the records from the DB, turn them
// into a MyControl.ascx, and then add them to my panel
protected override void OnInit(EventArgs e)
{
    base.OnInit(e);

    // get my List<SomethingFromDB> ordered by value and iterate through, 
    // adding controls to the control collection
    List<SomethingFromDB> myList = remoteService.GetSomeListFromTheDB();
    foreach(SomethingFromDB something in List<SomethingFromDB>)
    {
        // load a new MyControl.ascx
        MyControl myControl = (MyControl )LoadControl("~/Controls/MyControl .ascx");
        // populate the values of myControl with the "something"
        this.populateMyControl(something);
        // dynamically add the control to my panel
        this.myPanel.Add(myControl);     
        // subscribe to event
        myControl.SomeArbitraryEvent += new EventHandler(MyArbitraryHandler);
    }

    // This event gets fired by a magical control on the page and passes a 
    // new SomethingFromDB which needs to be inserted into the DB and then 
    // dynamically inserted into the Controls collection at the specified index
    private void SomeOtherControl_ClickInsert(object sender, MyControlEventArgs e)
    {
        // insert this record into the DB             
        remoteService.InsertIntoDB(e.SomethingFromDB);     
        // dynamically load this control
        MyControl myControl = (MyControl )LoadControl("~/Controls/MyControl .ascx");
        // get the index into which we will be inserting this control
        int index = e.NewIndex;                   
        //dynamically add the control to my panel at the specified index.
        // THIS DOES NOT ADJUST THE UNIQUEID VALUES ACCORDINGLY
        // AND IS THE SOURCE OF MY PROBLEM!
        this.myPanel.AddAt(index, myControl);
    }

Si prega di aiuto. Questo mi sta uccidendo. Se avete bisogno di ulteriori informazioni o hai domande per favore fatemelo sapere e io sarei felice di fornire più informazioni. Apprezzo molto il vostro aiuto!

È stato utile?

Soluzione

Per far funzionare la numerazione automatica, si desidera che i controlli da aggiungere al pannello nello stesso ordine per ogni postback. Ovviamente, su un postback, i controlli devono avere loro ID univoco assegnato, altrimenti non otterrebbe l'evento di controllo.

UniqueID è inizializzata al primo utilizzo per il valore della proprietà Control.ID *. Se la proprietà non è impostata, viene generato automaticamente come ctlxx, come avete osservato. Una volta assegnato, UniqueID di un controllo è in sola lettura.

Quindi, se si dispone di una qualche forma di chiave primaria, è possibile impostare la proprietà ID del controllo quando lo si crea sulla base di tale chiave primaria. Il UniqueID sarà quindi impostato su tale valore al caricamento della pagina il suo stato.

  • Nota:. La proprietà UniqueID è in realtà una combinazione di prefisso del contenitore di denominazione e la proprietà ID

Altri suggerimenti

Si prega di utilizzare il seguente attributo nella direttiva di pagina.

MaintainScrollPositionOnPostback = true

Questo aiuta, credo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top