我有被动态添加到自定义的GridView一个TemplateField。

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

在响应于电网命令(插入/更新/删除),一个称为GetRowControls方法被调用,其遍历在特定gridrow的列,并增加了它的每个控件的一个词典。

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

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

...

因此,这工作正常的编程加入声明方式添加两个模板字段和绑定控件,以及动态非模板字段。

但是当控制是一个TemplateField控制动态添加ctrl.ID总是空和上述因此该语句会抛出异常。

我看着这个与反射,因为我发现,当我在2005年即VS检查的变量在即时窗口中按下Ctrl,ctrl.ID将列出的值。因为我已经确定,这是因为在即时窗口中列出?CTRL中,proprty ClientID的被称为客户端ID和调用EnsureId(),进而设置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;
    }
}

所以我假设客户端ID,唯一ID和ID均为空 - 尽管如上述刚刚读取前两个将触发所有被设置。还要注意的是NamingContainer不为空。已被设定。

因此,对于这个解决方法是相当简单,即检查ctrl.ID == NULL,如果是简单的阅读ctrl.ClientID。而这就是我做了什么,因为时间上来说我真的得工作再上一个蠕动。但我仍然有兴趣的,如果有人知道它关闭他们的头顶部的答案。

为什么是一个子控制的ID值,动态地添加的TemplateField的,从其他控件的设置在不同的时间?

有帮助吗?

解决方案

这并不是说他们的行为方式不同,而且几乎总是当你添加控件声明你设定的ID的时候了。尝试添加一个标签,没有标识的页面和浏览控件集合,并检查自己的ID,这将是空的(确保不显示其clientID的,因为它会得到ID填写):

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

另外请注意,如果你运行它,这样你得到一个跨度,没有ID。

其他提示

弗雷迪是正确的。

您分别负责InstantiateIn方法内设置的ID。并且它是有道理的客户端ID的自动生成它们,除非另有说明。

在声明得到控制页面编译期间由页面生成器分配其ID。如果你看一下在“临时ASP.NET文件夹”生成的临时文件的.cs一个,你会发现这样的事情(编译指示剥离):

//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;
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top