¿Cuándo un control en una programación añaden TemplateField han establecido su propiedad ID?

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

Pregunta

Tengo un TemplateField que se agrega dinámicamente a un GridView personalizado.

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;
        }
    }

En respuesta a un comando de rejilla (insertar / actualizar / borrar), un método llamado GetRowControls se llama que itera a través de las columnas de la GridRow en particular, y añade cada uno de sus controles a un diccionario.

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

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

...

Así que esto funciona bien para los controles tanto de campo de plantilla y los consolidados agregados de forma declarativa, así como los campos dinámicos no-plantilla agregados programáticamente.

Sin embargo, cuando el control es un control TemplateField añadió dinámicamente ctrl.ID siempre es nula y, por tanto, la declaración anterior produce una excepción.

He mirado en esto con reflector porque he encontrado que cuando examiné la variable en la ventana inmediata en VS 2005 decir? Ctrl, ctrl.ID enumeraría un valor. ya he establecido que esto se debe a que en el listado? ctrl en la ventana inmediata, la ClientID proprty se llama y llama ClientID EnsureId (), que a su vez establece 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;
    }
}

Así que estoy asumiendo que ClientID, ID Única e ID son todos nulos - a pesar de que el anterior sólo leer los dos primeros se disparará todos estos se ajustan. También tenga en cuenta que NamingContainer no es nulo. Se ha establecido.

Así que el trabajo alrededor de esto es bastante simple, es decir comprobar ctrl.ID == null y si es así, simplemente leer ctrl.ClientID. Y eso es lo que he hecho, porque el tiempo sabia que realmente ha conseguido obtener un retorcerse sobre. Pero todavía estoy interesado en la respuesta si alguien sabe que la parte superior de sus cabezas.

¿Por qué es el valor de ID de un control de control, de un TemplateField añadido dinámicamente, establecer en un momento diferente de la de otros controles?

¿Fue útil?

Solución

No es que se comportan de manera diferente, pero que casi siempre cuando se agrega un control mediante declaración que establecen el ID de inmediato. Trate de añadir una etiqueta sin ID a una página y navegar por la colección de control y verificar su identificación, será nulo (asegúrese de no mostrar su ClientId ya que conseguiría el ID de llenado):

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

Tenga en cuenta también que si se ejecuta como el que se obtiene un lapso sin ID.

Otros consejos

Freddy es correcta.

Su son responsables de establecer los identificadores dentro del método InstantiateIn. Y tiene sentido que ClientId les genera automáticamente si no se especifica lo contrario.

Los controles declarativos obtener sus identificadores asignados por un constructor de página durante la compilación de una página. Si se va a mirar uno de los archivos temporales generados .cs en la carpeta "Archivos temporales de ASP.NET", que iba a encontrar algo como esto (pragmas despojados):

//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;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top