У меня есть TemplateField, который динамически добавляется в пользовательский GridView.
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, который перебирает столбцы в конкретной решетке и добавляет каждый из его элементов управления в словарь.
Dictionary<string, WebControl> GetRowControls(GridViewRow row)
...
rowControls.Add(ctrl.ID, (WebControl)ctrl);
...
Так что это прекрасно работает как для полей шаблона и связанных элементов управления, добавленных декларативно, так и для динамически не шаблонных полей, добавленных программно.
Однако, когда элемент управления является элементом управления TemplateField, добавляемым динамически, ctrl.ID всегда равен null, и поэтому приведенное выше выражение вызывает исключение.
Я посмотрел на это с помощью Reflector, потому что обнаружил, что когда я проверял переменную в ближайшем окне в VS 2005, то есть? Ctrl, ctrl.ID указывал бы значение. С тех пор я установил, что это происходит потому, что в листинге? Ctrl в ближайшем окне вызывается proprty ClientID, а ClientID вызывает 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;
}
}
Итак, я предполагаю, что ClientID, UniqueId и ID имеют нулевое значение - хотя, как указано выше, простое чтение первых двух вызовет установку всех параметров. Также обратите внимание, что NamingContainer не является нулевым. Это было установлено.
Так что обойти это довольно просто, то есть проверить ctrl.ID == null и, если это так, просто прочитать ctrl.ClientID. И это то, что я сделал, потому что со временем я действительно должен шевелиться. Но я все еще заинтересован в ответе, если кто-нибудь знает его по макушке.
Почему значение идентификатора дочернего элемента управления, динамически добавленного TemplateField, отличается от времени других элементов управления?