Gridview,对象引用未设置为对象的实例

时间:2022-12-04 15:10:47

I can't find the source for this problem. I debugged my code and it ends fine and it does what it's requested(deletion of a page entry from the database), however it returns this after the code ends:

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

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

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

The code for ListPages.aspx is:

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>

The code for ListPages.apsx.cs:

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");
    }
}

}

}

I think there's something wrong with the GridView. When the delete button is clicked my code doesn't go straight to the event method but goes to PageLoad again, renders the GridView again (supposedly, in the code) and then goes to the method event. Please help me I'm stuck with this.

我认为GridView有问题。单击删除按钮时,我的代码不会直接转到事件方法,而是再次转到PageLoad,再次呈现GridView(据说,在代码中),然后转到方法事件。请帮助我,我坚持这个。

1 个解决方案

#1


1  

Wrap CreatePageList in if(!IsPostBack):

在if(!IsPostBack)中包装CreatePageList:

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

The complete lifecycle is run through on every postback. That is normal. However, you should not databind the grid to it's DataSource from Page_Load on every postback if ViewState is enabled(default). Do that only if something has changed, so for example after you have deleted a row from the delete-event.

每个回发都会贯穿整个生命周期。这很正常。但是,如果启用了ViewState,则不应在每次回发时从Page_Load将网格数据绑定到DataSource(默认)。只有当某些内容发生了变化时才这样做,例如,在删除了一个删除事件的行之后。

Otherwise all changes are lost since the previous values are loaded from database, also events aren't triggered anymore.

否则,由于从数据库加载了先前的值,所有更改都将丢失,因此不再触发事件。

Update You are also creating controls dynamically in RowDataBound. That is not a good place, use RowCreated instead. Dynamic controls must be recreated on every postback. But RowDataBound is called only if the GridView is databound which is not necessarily on every postback. As opposed to this RowCreated is called on every postback.

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

But since you are setting the NavigateUrl in RowDataBound which is derived from an ID of the underlying DataItem you have to create the Hyperlink in RowCreated as mentioned with an appropriate ID. Use this ID in RowDataBound to find the Hyperlink and set it's NavigateUrl property.

但是,由于您在RowDataBound中设置NavigateUrl,它是从基础DataItem的ID派生的,因此您必须使用适当的ID在RowCreated中创建超链接。在RowDataBound中使用此ID可查找超链接并设置其NavigateUrl属性。

The important point is that it will be recreated always, but it's NavigateUrl property is set just once.

重要的一点是它将永远重新创建,但它的NavigateUrl属性只设置一次。

#1


1  

Wrap CreatePageList in if(!IsPostBack):

在if(!IsPostBack)中包装CreatePageList:

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

The complete lifecycle is run through on every postback. That is normal. However, you should not databind the grid to it's DataSource from Page_Load on every postback if ViewState is enabled(default). Do that only if something has changed, so for example after you have deleted a row from the delete-event.

每个回发都会贯穿整个生命周期。这很正常。但是,如果启用了ViewState,则不应在每次回发时从Page_Load将网格数据绑定到DataSource(默认)。只有当某些内容发生了变化时才这样做,例如,在删除了一个删除事件的行之后。

Otherwise all changes are lost since the previous values are loaded from database, also events aren't triggered anymore.

否则,由于从数据库加载了先前的值,所有更改都将丢失,因此不再触发事件。

Update You are also creating controls dynamically in RowDataBound. That is not a good place, use RowCreated instead. Dynamic controls must be recreated on every postback. But RowDataBound is called only if the GridView is databound which is not necessarily on every postback. As opposed to this RowCreated is called on every postback.

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

But since you are setting the NavigateUrl in RowDataBound which is derived from an ID of the underlying DataItem you have to create the Hyperlink in RowCreated as mentioned with an appropriate ID. Use this ID in RowDataBound to find the Hyperlink and set it's NavigateUrl property.

但是,由于您在RowDataBound中设置NavigateUrl,它是从基础DataItem的ID派生的,因此您必须使用适当的ID在RowCreated中创建超链接。在RowDataBound中使用此ID可查找超链接并设置其NavigateUrl属性。

The important point is that it will be recreated always, but it's NavigateUrl property is set just once.

重要的一点是它将永远重新创建,但它的NavigateUrl属性只设置一次。