什么时候在控制编程方式添加模板列有其ID属性设置?
-
22-08-2019 - |
题
我有被动态添加到自定义的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;
}