Abid Ali
Abid Ali

Reputation: 1747

Object reference not set to an instance of an object

i am stuck with this error since last few hours.. i dont know what am i doing wrong here..

    <script type="text/javascript">
    function viewProfile(index)
    {
        var GridID = document.getElementById("PersonGridView");
        var row=GridID.rows[parseInt(index)+1];
        window.open('detailsid.aspx?'+row);
    }
    </script>

        <Columns>
            <asp:BoundField HeaderText="First Name" DataField="FirstName" />
            <asp:BoundField HeaderText="Last Name" DataField = "LastName" />
            <asp:BoundField HeaderText="HomePhoneNumber" DataField="HomePhoneNumber" />
            <asp:TemplateField HeaderText="ViewDetails">
            <ItemTemplate>
            <asp:Button ID="Deatils" runat="server" Text="Details" />
            </ItemTemplate>    

            </asp:TemplateField>

            <asp:TemplateField HeaderText="Actions">
            <ItemTemplate>
            <asp:Button ID="Modify" runat="server" Text="Modify" />
            <asp:Button ID="Delete" runat="server" Text="Delete" />

            </ItemTemplate>
            </asp:TemplateField>


        </Columns>


        <FooterStyle BackColor="#CCCC99" />
        <PagerStyle BackColor="#F7F7DE" ForeColor="Black" HorizontalAlign="Right" />
        <SelectedRowStyle BackColor="#CE5D5A" Font-Bold="True" ForeColor="White" />
        <HeaderStyle BackColor="#6B696B" Font-Bold="True" ForeColor="White" />
        <AlternatingRowStyle BackColor="White" />
    </asp:GridView>
</div>
</form>

<p> Code Behind : 
protected void PersonGridView_RowDataBound(object sender, GridViewRowEventArgs e)
        {

               if (e.Row.RowType == DataControlRowType.DataRow)
            {
         var ID = PersonGridView.DataKeys[e.Row.RowIndex]["ID"].ToString();

                Button btnDetails = (Button)FindControl("Details");
                Button btnModify = (Button)FindControl("Modify");
                Button btnDelete = (Button)FindControl("Delete");
                btnModify.CommandName = "Modify";
                btnDelete.CommandName = "Delete";
                btnDetails.CommandName = "Details";
                btnDelete.CommandArgument = btnModify.CommandArgument = string.Format("{0}", ID);
                btnDetails.Attributes["onclick"] = string.Format("viewProfile({0}); return false;", ID);


            }
        }

Upvotes: 0

Views: 12702

Answers (2)

David
David

Reputation: 218827

Is this the line that's throwing the error?:

var ID = PersonGridView.DataKeys[e.Row.RowIndex]["ID"].ToString();

This line is referencing an array item by index in two different places, so you'll need to do a little debugging to determine which one is the problem. Basically, either PersonGridView.DataKeys[] doesn't have an index which matches e.Row.RowIndex or that item doesn't have an index which matches "ID". You'll need to either step through a debugger to examine those values at runtime or toss in some debugging code (Response.Write statements and such to examine values) to see what's going on.

One common error is that the DataGridView is running this code on non-data rows. Header, footer, etc. You can expand the scope of the if statement to address that. Reference the indexes within the conditional rather than outside of it.

Edit: (In response to your comment below)

Is btnDetails set to an instance of an object? I'm guessing it isn't. You'll need to continue the debugging and see if the control you're trying to find is actually there. I notice that it's in a separate ItemTemplate and TemplateField from the other buttons. Is that causing an issue perhaps? I'm not entirely familiar with these server controls so I'm not sure off-hand.

I should take a moment to point out that your code here is very fragile. The problems you've been experiencing are the result of this. You're referencing arrays by indexes manually, including the use of a "magic string" to reference them. You might want to toss in some error checking for that. You're also casting and later using objects without checking if they exist first. FindControl can very easily return a null reference, such as when the control isn't found.

Throwing in tons of error checking is kind of part of the reality of using these web forms controls and their old data binding methods. A lot of extra code, but that's how it goes with these controls and directly binding to weakly-typed DataSets and such.

Upvotes: 0

amit_g
amit_g

Reputation: 31250

Change

        var ID = PersonGridView.DataKeys[e.Row.RowIndex]["ID"].ToString();
        if (e.Row.RowType == DataControlRowType.DataRow)
        {

to

        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            var ID = PersonGridView.DataKeys[e.Row.RowIndex]["ID"].ToString();

i.e. extract the DataKeys only when the row is of DataRow and not for Header/Footer etc.

Upvotes: 2

Related Questions