Quando si fa un controllo in un livello di codice aggiunto TemplateField aver impostato la proprietà ID?

StackOverflow https://stackoverflow.com/questions/703987

Domanda

Ho un TemplateField che viene dinamicamente aggiunto a un GridView personalizzato.

void ITemplate.InstantiateIn(System.Web.UI.Control container)
    {
        switch (_templateType)
        {
            case ListItemType.Header:
                if (this.ParentGridView.ShowDeleteHeaderImage)
                {
                    Image hImg = new Image();
                    hImg.ImageUrl = this.ParentGridView.DeleteHeaderImageUrl;
                    hImg.AlternateText = "Mark for Deletion";
                    container.Controls.Add(hImg);
                }
                else
                {
                    Label l = new Label();
                    l.Text = "Del";
                    container.Controls.Add(l);
                }
                break;
            case ListItemType.Item:
                container.Controls.Add(new CheckBox());
                break;
            case ListItemType.EditItem:
                break;
            case ListItemType.Footer:
                QLImageButton deleteButton = new QLImageButton();
                deleteButton.Settings.ImageId = "cmdQLGVDelete";
                deleteButton.Settings.ImageUrl = this.ParentGridView.DeleteImageUrl;
                deleteButton.CommandName = "Delete";
                container.Controls.Add(deleteButton);
                break;
        }
    }

In risposta a un comando griglia (inserimento / aggiornamento / cancellazione), un metodo chiamato GetRowControls viene chiamato che scorre attraverso le colonne del particolare gridrow, e aggiunge ciascuno dei suoi controlli a un dizionario.

Dictionary<string, WebControl> GetRowControls(GridViewRow row)
...

rowControls.Add(ctrl.ID, (WebControl)ctrl);

...

Quindi, questo funziona bene sia per il campo modello e rilegati controlli aggiunti in modo dichiarativo, così come i campi dinamico non template aggiunto programatically.

Tuttavia, quando il controllo è un controllo TemplateField aggiunto dinamicamente ctrl.ID è sempre nullo e quindi la dichiarazione di cui sopra genera un'eccezione.

Ho guardato in questo con Reflector, perché ho scoperto che quando ho esaminato la variabile nella finestra immediata in VS 2005 vale a dire? Ctrl, ctrl.ID elencherebbe un valore. Da allora ho stabilito che questo è perché nell'elencare? Ctrl nella finestra immediata, il ClientID proprty viene chiamato e chiama ClientID EnsureID (), che a sua volta imposta ID.

public virtual string ClientID
{
    get
    {
        this.EnsureID();
        string uniqueID = this.UniqueID;
        if ((uniqueID != null) && (uniqueID.IndexOf(this.IdSeparator) >= 0))
        {
            return uniqueID.Replace(this.IdSeparator, '_');
        }
        return uniqueID;
    }
}

Così sto supponendo che ClientID, UniqueId e ID sono tutti nulli - anche se come sopra solo leggendo i primi due attiverà tutte da impostare. Si noti inoltre che NamingContainer non è nullo. Esso è stato impostato.

Così il lavoro in giro per questo è abbastanza semplice cioè verificare la presenza di ctrl.ID == null e se è così semplicemente leggere ctrl.ClientID. E questo è quello che ho fatto perché il tempo di saggio ho davvero avuto modo di ottenere un guizzo su. Ma io sono ancora interessato alla risposta, se qualcuno sa che la parte superiore della testa.

Perché è il valore ID di un controllo figlio, di un TemplateField aggiunto in modo dinamico, impostare in un momento diverso da quello degli altri controlli?

È stato utile?

Soluzione

Non è che si comportano in modo diverso, ma che quasi sempre quando si aggiunge un controllo dichiarativo di impostare l'ID subito. Prova ad aggiungere un'etichetta senza ID a una pagina e sfogliare la raccolta di controllo e verificare il suo ID, sarà nullo (fare attenzione a non mostrare la sua IDcliente perché sarebbe ottenere il pieno ID):

<asp:Label runat="server">something</asp:Label>

Si noti inoltre che se si esegue in quel modo si ottiene un arco senza ID.

Altri suggerimenti

Freddy è corretta.

Il tuo è responsabile della definizione ID all'interno del metodo InstantiateIn. E ha senso che clientid li genera automaticamente, se non diversamente specificato.

I controlli dichiarativa ottengono il loro ID assegnati da un costruttore pagina durante la compilazione di una pagina. Se si dovesse guardare uno dei file temporanei cs generati nella cartella "file temporanei di ASP.NET", che si può trovare qualcosa di simile (pragma spogliati):

//creating a template field, where CopiledBindableTemplateBuilder is the ITemplate
//and its InstantiateIn = @__BuildControl__control9
@__ctrl.ItemTemplate = new System.Web.UI.CompiledBindableTemplateBuilder(
    new System.Web.UI.BuildTemplateMethod(this.@__BuildControl__control9),
    new System.Web.UI.ExtractTemplateValuesMethod(this.@__ExtractValues__control9));

//and @__BuildControl__control9 calling @__BuildControlButton1
private global::System.Web.UI.WebControls.Button @__BuildControlButton1()
{
    global::System.Web.UI.WebControls.Button @__ctrl;

    @__ctrl = new global::System.Web.UI.WebControls.Button();
    this.Button1 = @__ctrl;
    @__ctrl.ApplyStyleSheetSkin(this);
    @__ctrl.ID = "Button1"; //<-- here it gets an ID
    @__ctrl.Text = "Button";
    return @__ctrl;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top