GridView FindControl возвращает ноль, когда установлен HeaderText - PullRequest
0 голосов
/ 04 февраля 2009

У меня есть GridView ...

<asp:GridView EnableViewState="true" 
                ID="grdResults" 
                runat="server" 
                CssClass="resultsGrid" 
                OnRowDataBound="grdResults_OnRowDataBound" 
                AutoGenerateColumns="false" 
                HeaderStyle-CssClass="header" 
                OnRowCommand="grdResults_OnRowCommand">
    <Columns>
       <asp:TemplateField>
           <ItemTemplate>
               <asp:Label ID="lblView" 
                           runat="server" 
                           Visible="false" 
                           Text="View">
               </asp:Label>
               <asp:HyperLink ID="hypEdit" 
                               runat="server" 
                               Visible="false" 
                               Text="(Edit)" 
                               CssClass="edit">
               </asp:HyperLink>
               <asp:LinkButton ID="btnDelete" 
                               runat="server" 
                               Visible="false" 
                               Text="(Delete)" 
                               CssClass="delete" 
                               CommandName="DeleteItem" 
                               OnClientClick="return confirm('Are you sure you want to delete?')">
               </asp:LinkButton>
               <asp:HyperLink ID="hypSelect" 
                               runat="server" 
                               Visible="false" 
                               Text="(Select)" 
                               CssClass="select">
               </asp:HyperLink>
           </ItemTemplate>
       </asp:TemplateField>
   </Columns>
</asp:GridView>

Это один статический столбец, содержащий метку, две гиперссылки и кнопку ссылки, а также ряд динамически генерируемых столбцов ...

private void SetupColumnStructure(IEnumerable<string> columnNames)
{
    var columnNumber = 0;
    foreach (var columnName in columnNames)
    {
        var templateColumn = new TemplateField
                                 {
                                     ItemTemplate = new CellTemplate(columnName)
                                 };
       grdResults.Columns.Insert(columnNumber, templateColumn);
       columnNumber++;
    }
}

Как часть обработчика OnRowDataBound, я извлекаю один из элементов управления в статически столбце и устанавливаю некоторые атрибуты для него ...

protected void grdResults_OnRowDataBound(object sender, GridViewRowEventArgs e)
{
    .
    .
    .
    var row = e.Row;
    var rowData = row.DataItem as Dictionary<string, object>;
    if (rowData != null)
    {
       if ((bool)rowData[displayEditLink])
       {
           var hypEdit = (HyperLink)row.FindControl("hypEdit");
           hypEdit.NavigateUrl = "~/Pages/Edit.aspx?action=Edit&objectType=" + rowData[objectTypeLiteral] + "&id=" + rowData[objectIdLiteral];
           hypEdit.Visible = true;
       }
   }
   .
   .
   .
}

Это все работает нормально, но имена столбцов не отображаются. Поэтому я затем модифицирую метод SetupColumnStructure, чтобы HeaderText устанавливался в поле шаблона следующим образом ...

private void SetupColumnStructure(IEnumerable<string> columnNames)
{
    var columnNumber = 0;
    foreach (var columnName in columnNames)
    {
        var templateColumn = new TemplateField
                                 {
                                     ItemTemplate = new CellTemplate(columnName),
                                     HeaderText = columnName
                                };
       grdResults.Columns.Insert(columnNumber, templateColumn);
       columnNumber++;
    }
}

По какой-то причине это одно дополнительное изменение строки вызывает row.FindControl ("hypEdit"); вызовите обработчик OnRowDataBound для возврата значения null. Может кто-нибудь увидеть что-то, что мне здесь не хватает, или кто-нибудь испытывал похожую проблему?

UPDATE

Я позаботился о том, чтобы здесь я не ссылался на строку верхнего или нижнего колонтитула. Кроме того, если я перехожу через исключение ссылки на объект, это происходит для каждого элемента в источнике данных.

Не уверен, поможет ли это, но, как я и ожидал, когда я прошел по коду, таблица сгенерировала все ожидаемые столбцы, но все ячейки (DataControlFieldCells) не содержат никаких элементов управления, когда установлен HeaderText, но все ожидаемые элементы управления, когда это не так установлен.

Все очень странно. Дайте мне знать, если вы можете найти что-нибудь еще.

Ответы [ 2 ]

0 голосов
/ 22 апреля 2009

Это потому, что искомый элемент управления содержится в другом элементе управления. FindControl () не просматривает наборы элементов управления. Вам нужно будет написать метод recursiveFindControl ().

Надеюсь, это немного поможет!

0 голосов
/ 04 февраля 2009

Когда вы добавили HeaderText, новый RowType был добавлен в сетку. Вам нужно проверить, какой тип строки вызвал событие OnRowDataBound, и предпринять соответствующее действие. В вашем случае, только проверка того, является ли e.Row.RowType типом DataRow, должна решить вашу проблему:

protected void grdResults_OnRowDataBound(object sender, GridViewRowEventArgs e)
{
     if(e.Row.RowType == DataControlRowType.DataRow)
     {
          if ((bool)rowData[displayEditLink])
          {
           var hypEdit = (HyperLink)row.FindControl("hypEdit");
           hypEdit.NavigateUrl = "~/Pages/Edit.aspx?action=Edit&objectType=" + rowData[objectTypeLiteral] + "&id=" + rowData[objectIdLiteral];
           hypEdit.Visible = true;
          }
     }
}
...