【问题标题】:Gridview, Object reference not set to an instance of an objectGridview,对象引用未设置为对象的实例
【发布时间】:2013-07-19 11:30:49
【问题描述】:

我找不到这个问题的根源。我调试了我的代码,它结束了,它完成了它的请求(从数据库中删除一个页面条目),但是它在代码结束后返回:

http://i.imgur.com/IO5zY5v.png

ListPages.aspx 的代码是:

<%@ Page Title="" Language="C#" MasterPageFile="~/admin/Admin.Master" AutoEventWireup="true" CodeBehind="ListPages.aspx.cs" Inherits="TopStart.admin.ListPages" %>

<asp:Content ContentPlaceHolderID="Main" runat="server">
                <div id="container" runat="server" class="full_w">
                <div class="h_title">Manage Your Pages</div>
                <h2>Page Management</h2>
                <p>This is a list of all your website pages. Use the icons on the last column to perform various operations on a page.</p>

            <div class="entry">
                <div class="sep"></div>
            </div>
            <asp:GridView ID="PageList" runat="server" AllowPaging="True" OnRowDataBound="PageList_RowDataBound" OnPageIndexChanging="PageList_PageIndexChanging">
                <PagerStyle CssClass="pager" />
            </asp:GridView>

            <div class="entry">
                <div class="sep"></div>     
                <a class="button add" href="AddPage.aspx">Add new page</a> <a class="button" href="">Categories</a> 
            </div>
        </div>

ListPages.apsx.cs 的代码:

using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;

namespace TopStart.admin
{
    public partial class ListPages : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
                CreatePageList();
        }

    protected void CreatePageList()
    {
        Database db = new Database("mySqlCon");

        string query = "SELECT p.id, p.title, p.slug, u.username, c.categories FROM pages as p LEFT JOIN users AS u ON p.user_id = u.id LEFT JOIN categories AS c ON p.category_id = c.id";

        DataTable dt = db.Query(query);
        dt.Columns.Add(new DataColumn("Modify"));

        PageList.DataSource = dt;
        PageList.DataBind();
    }

    protected void PageList_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.Header)
        {
            e.Row.Cells[5].Width = new Unit("65px");
        }
        else if (e.Row.RowType == DataControlRowType.DataRow)
        {
            HyperLink edit = new HyperLink();
            edit.NavigateUrl = "EditPage.aspx?id=" + e.Row.Cells[0].Text;
            edit.CssClass = "table-icon edit";
            edit.Attributes.Add("title", "Edit");

            HyperLink archive = new HyperLink();
            archive.NavigateUrl = "Archive.aspx?id=" + e.Row.Cells[0].Text;
            archive.CssClass = "table-icon archive";
            archive.Attributes.Add("title", "Archive");

            LinkButton delete = new LinkButton();
            delete.CssClass = "table-icon delete";
            delete.Attributes.Add("title", "Delete");
            delete.Attributes.Add("id", e.Row.Cells[0].Text);
            delete.ID = e.Row.Cells[0].Text;
            delete.Click += new EventHandler(delete_Click);

            e.Row.Cells[5].Controls.Add(edit);
            e.Row.Cells[5].Controls.Add(archive);
            e.Row.Cells[5].Controls.Add(delete);
        }
    }

    protected void PageList_PageIndexChanging(object sender, GridViewPageEventArgs e)
    {
        PageList.PageIndex = e.NewPageIndex;
        PageList.DataBind();
    }

    protected void delete_Click(object sender, EventArgs e)
    {
        LinkButton lb = (LinkButton)sender;

        Database db = new Database("mySqlCon");
        string query = "DELETE FROM pages WHERE id = @id";

        MySqlParameter pId = new MySqlParameter("@id", MySqlDbType.Int32, 4);
        pId.Value = lb.ID;

        if (db.MQuery(query, pId))
        {
            container.InnerHtml = "<div class=\"h_title\">Success</div>\n<div class=\"n_ok\"><p>Page was deleted. Redirecting...</p></div>";
        }
        else
        {
            container.InnerHtml = "<div class=\"h_title\">Failure</div>\n<div class=\"n_error\"><p>Page couldn't be deleted. Redirecting...</p></div>";
        }

        Response.AddHeader("REFRESH", "3;URL=ListPages.aspx");
    }
}

}

我认为 GridView 有问题。当单击删除按钮时,我的代码不会直接转到事件方法,而是再次转到 PageLoad,再次呈现 GridView(假设在代码中),然后转到方法事件。请帮帮我,我被这个卡住了。

【问题讨论】:

    标签: c# asp.net gridview webforms linkbutton


    【解决方案1】:

    CreatePageList 包裹在if(!IsPostBack) 中:

    protected void Page_Load(object sender, EventArgs e)
    {
        if(!IsPostBack)
            CreatePageList();
    }
    

    每次回发都会贯穿完整的生命周期。这是正常的。但是,如果启用了 ViewState(默认),则不应在每次回发时将网格数据绑定到来自 Page_Load 的数据源。仅当某些情况发生变化时才这样做,例如 您从删除事件中删除了一行。

    否则所有更改都会丢失,因为以前的值是从数据库加载的,也不会再触发事件。

    更新您还在RowDataBound 中动态创建控件。那不是一个好地方,请改用RowCreated。必须在每次回发时重新创建动态控件。但是 RowDataBound 仅在 GridView 是数据绑定时才被调用,这不一定在每个回发中。与此相反,RowCreated 在每次回发时都会调用。

    但是由于您在RowDataBound 中设置NavigateUrl,它是从底层DataItemID 派生的,因此您必须在RowCreated 中创建Hyperlink,正如提到的那样,使用适当的ID .在RowDataBound 中使用此ID 来查找Hyperlink 并将其设置为NavigateUrl 属性。

    重要的是它总是会重新创建,但它的NavigateUrl 属性只设置一次。

    【讨论】:

    • 在他的代码中,他替换了div(id = 容器)的内容,他在其中放置了GridView,所以网格视图也从页面生命周期中删除了吗?我认为这就是他得到例外的原因。
    • @gzaxx:他应该在RowCreated 中创建动态控件,并设置它们依赖于来自RowDataBound 的数据源的属性。编辑了我的答案。
    • 我不能在 RowCreated 中做所有事情吗?我刚试过,它没有呈现控件。那么如何给RowCreated设置一个合适的ID,然后在RowDataBound处使用呢,我这里搞糊涂了。是的,当触发删除事件方法时,我将容器 HTML 更改为成功消息,然后再次重定向到同一页面以再次显示 GridView。
    • @GlendGjermeni:你不能在RowCreated 中做所有事情,因为你没有DataSourceGridView.DataSourcee.Row.DataItem 在回发时都是空的。你可以选择你想要的ID,例如edit.Id = "editLink"。然后在RowDataBound:var editLink = (Hyperlink)e.Row.FindControl("editLink");。使用 RowDataBound 中的 e.Row.DataItem 获取该行的所有数据。
    • 我不会为几行的所有编辑控件提供相同的 ID 吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多