Fran Martinez
Fran Martinez

Reputation: 679

Delete a column within a Repeater

I'm attempting to delete a header cell and its columns depending on the content of a string. When I run the web application I receive the error: NullReferenceException was handled by user code.

The problem is how I find the control. It appears to be null. However, my intended result is if the condition is true, then the column should not be visible (HTML perspective).

My Code-Behind code:

protected void rptBillHeaders_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    RepeaterItem item = e.Item;
    if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
    {
        Repeater rptLineItems = ((Repeater)item.FindControl("rptLineItems"));
        rptLineItems.DataSource = currentBill.LineItemsByVersion[rowNumber].Sort(BillLineItem.SortColumn.LineItemNumber, System.Data.SqlClient.SortOrder.Ascending);
        rptLineItems.DataBind();
        rowNumber++;
    }

    Control HeaderTemplate = rptBillHeaders.Controls[0].Controls[0];

    if (lit.ObjectType.C == "C")
    {
        e.Item.FindControl("DocColumn").Visible = false;
        e.Item.FindControl("DocHeader").Visible = false;
    }
}

In my .aspx file I have:

<asp:Repeater runat="server" ID="rptBillHeaders" OnItemDataBound="rptBillHeaders_ItemDataBound">
    <HeaderTemplate>
        <table width="98%" align="center" class="grid" cellpadding="0" cellspacing="0" style="border:solid 1px #000000; border-top:none 0px #FFFFFF;">
            <tr class="gridHeaderRow">
                <th>&nbsp</th>
                <th><asp:Label runat="server" ID="billVersionLabel" ></asp:Label></th> 
                <th>Action Type</th>
                <th id="DocHeader" runat="server">Doc #</th>
                <th>Status</th>
                <th>Total Amount</th>
                <th>Submitted By</th>
                <th>Date Submitted</th>
                <th>Date Processed</th>
            </tr>
    </HeaderTemplate>
    <ItemTemplate>
        <tr class="gridRow gridRowThickTopBorder">
            <td style="padding: 5px;">
                <div id="divBillIcon" align="center" style="text-align:center;" class="icon ui-state-default ui-corner-all">
                    <span class="ui-icon ui-icon-plus"></span>
                </div>
            </td>
            <td class="Center"><%# ((int)Container.DataItem) %></td>
            <td><%# GetActionType((int)Container.DataItem) %> </td>
            <td id="DocColumn" runat="server"><%# GetDocNumber((int)Container.DataItem) %> </td>
            <td><%# val.get(cache.BillStatusDict, currentBill.ProcessedStatusesByVersion[((int)Container.DataItem)].Status, "&nbsp;") %></td>
            <td class="Right">$<%# currentBill.LineItemsByVersion[((int)Container.DataItem)].GetTotalAmount().ToString("2") %></td>
            <td><%# currentBill.PendingStatusesByVersion[((int)Container.DataItem)].CreateWebUserName %></td>
            <td><%# convert.ToDateString(convert.ToDateTimeQ(currentBill.PendingStatusesByVersion[((int)Container.DataItem)].CreateDate)) %></td>
            <td><%# convert.ToDateString(convert.ToDateTimeQ(currentBill.ProcessedStatusesByVersion[((int)Container.DataItem)].CreateDate)) %></td>
        </tr>

I've tried changing the type of the label in each of the columns, like adding a label id and a cell id, but that causes the same error.

Upvotes: 1

Views: 1270

Answers (2)

Vijjendra
Vijjendra

Reputation: 25223

Please remove your Header from HeaderTemplate and keep this above of the Repeter.

<table width="98%" align="center">
    <tr class="gridHeaderRow">
        <th>&nbsp</th>
        <th>
            <asp:Label runat="server" ID="billVersionLabel"></asp:Label></th>
        <th>Action Type</th>
        <th id="DocHeader" runat="server">Doc #</th>
        <th>Status</th>
        <th>Total Amount</th>
        <th>Submitted By</th>
        <th>Date Submitted</th>
        <th>Date Processed</th>
    </tr>
    <asp:Repeater runat="server" ID="rptBillHeaders" OnItemDataBound="rptBillHeaders_ItemDataBound">
        <ItemTemplate>
            <tr class="gridRow gridRowThickTopBorder">
                <td style="padding: 5px;">
                    <div id="divBillIcon" align="center" style="text-align: center;" class="icon ui-state-default ui-corner-all">
                        <span class="ui-icon ui-icon-plus"></span>
                    </div>
                </td>
                <td class="Center"><%# ((int)Container.DataItem) %></td>
                <td><%# GetActionType((int)Container.DataItem) %> </td>
                <td id="DocColumn" runat="server"><%# GetDocNumber((int)Container.DataItem) %> </td>
                <td><%# val.get(cache.BillStatusDict, currentBill.ProcessedStatusesByVersion[((int)Container.DataItem)].Status, "&nbsp;") %></td>
                <td class="Right">$<%# currentBill.LineItemsByVersion[((int)Container.DataItem)].GetTotalAmount().ToString("2") %></td>
                <td><%# currentBill.PendingStatusesByVersion[((int)Container.DataItem)].CreateWebUserName %></td>
                <td><%# convert.ToDateString(convert.ToDateTimeQ(currentBill.PendingStatusesByVersion[((int)Container.DataItem)].CreateDate)) %></td>
                <td><%# convert.ToDateString(convert.ToDateTimeQ(currentBill.ProcessedStatusesByVersion[((int)Container.DataItem)].CreateDate)) %></td>
            </tr>
        </ItemTemplate>
    </asp:Repeater>
</table>

Hide all the conditional Header and columns on the OnItemDataBound event of the Repeater with your required condition. like below

protected void rptBillHeaders_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        RepeaterItem item = e.Item;
        if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
        {
            Repeater rptLineItems = ((Repeater)item.FindControl("rptLineItems"));
            rptLineItems.DataSource = currentBill.LineItemsByVersion[rowNumber].Sort(BillLineItem.SortColumn.LineItemNumber, System.Data.SqlClient.SortOrder.Ascending);
            rptLineItems.DataBind();
            var DocColumn = (HtmlTableCell)e.Item.FindControl("DocColumn");
            if (lit.ObjectType.C == "C")
            {
                if (DocColumn != null)
                {
                    DocColumn.Visible = false;
                    DocHeader.Visible = false;
                }
            }
            rowNumber++;
        }
    }

Upvotes: 0

Martin Parenteau
Martin Parenteau

Reputation: 73731

You should look for each control in its own item type:

protected void rptBillHeaders_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    ...

    if (item.ItemType == ListItemType.Header)
    {
        ...
        e.Item.FindControl("DocHeader").Visible = false;
    }
    else if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
    {
        ...
        e.Item.FindControl("DocColumn").Visible = false;
    }
}

Upvotes: 1

Related Questions