【问题标题】:ASP.Net GridView RowUpdate not firing and RowUpdating doesn't have NewValuesASP.Net GridView RowUpdate 未触发且 RowUpdating 没有 NewValues
【发布时间】:2013-01-21 08:51:52
【问题描述】:

我有以下 GridView:

<asp:GridView ID="gridCar" runat="server" RowStyle-ForeColor="Black" AllowSorting="true" OnSorting="gridCar_Sorting" AutoGenerateEditButton="true" OnRowEditing="gridCar_RowEditing" OnRowCancelingEdit="gridCar_RowCancelingEdit" OnRowUpdating="gridCar_RowUpdating" OnRowUpdated="gridCar_RowUpdated"></asp:GridView>

我想更新编辑按钮选择的行。问题是,如果我尝试在gridCar_RowUpdating 中执行此操作,e.NewValues 将不包含已编辑的值,而是包含旧值。

我四处搜索,发现我可能不得不使用onRowUpdated 事件,但是我遇到了另一个问题;这个事件根本没有被触发。我尝试在gridCar_RowUpdating 中设置e.Cancel = false,但这并不能解决问题。

GridView 绑定到 DataTable。

编辑:这是我的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

using System.Data;

public partial class _Default : Page
{
    DataTable carsTable = new DataTable("cars");

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            carsTable.Columns.Add("CarID");
            carsTable.Columns.Add("CarRegNum");
            carsTable.Columns.Add("CarModel");
            carsTable.Columns.Add("CarType");
            carsTable.Columns.Add("CarOwner");

            carsTable.Rows.Add(1, "AAA-111", "Toyota", "Hatchback", "Matti");
            carsTable.Rows.Add(2, "BBB-222", "Mercedes-Benz", "Van", "Keijo");
            carsTable.Rows.Add(3, "CCC-333", "Renault", "Regular", "Matilda");

            carsTable.AcceptChanges();

            gridCar.DataSource = carsTable;
            gridCar.DataBind();
        }
    }

    protected string dataViewSortDirection(SortDirection direction)
    {
        switch (direction)
        {
            case SortDirection.Ascending:
                return "ASC";
            case SortDirection.Descending:
                return "DESC";
            default:
                throw new ArgumentOutOfRangeException();
        }
    }

    protected void gridCar_Sorting(object sender, GridViewSortEventArgs e)
    {
        gridCar.Sort(e.SortExpression, e.SortDirection);

        // update GridView
        gridCar.DataBind();
    }

    protected void gridCar_RowEditing(object sender, GridViewEditEventArgs e)
    {
        gridCar.EditIndex = e.NewEditIndex;
        gridCar.DataBind();
    }

    protected void gridCar_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
    {
        gridCar.EditIndex = -1;
        gridCar.DataBind();
    }

    protected void gridCar_RowUpdating(object sender, GridViewUpdateEventArgs e)
    {
        labelDebug.Text += "b";
        //gridCar.EditIndex = -1;
        //gridCar.DataBind();
    }

    protected void gridCar_RowUpdated(object sender, GridViewUpdatedEventArgs e)
    {
        labelDebug.Text += "a";
        gridCar.EditIndex = -1;
        gridCar.DataBind();
    }
}

【问题讨论】:

  • 在 ViewState 中存储数据表不是一个好习惯,因为它会增加页面大小并降低性能,而且 ViewState 可以在客户端被破译,因此 DataTable 不安全。
  • @TimSchmelter 在我的情况下你会建议我做什么?
  • 正如我对我的回答所评论的那样,您不需要保留数据源,因为无论如何数据都存储在 GridView 的 ViewState 中。所以e.OldValuese.NewValues 已设置,即使您没有将DataTable 从服务器传输到客户端并返回到服务器。但是您需要确保它仅在第一次加载时才被数据绑定(!IsPostBack)。

标签: c# asp.net events gridview datatable


【解决方案1】:

您确定您没有在回发时对GridView 进行数据绑定吗?你应该只这样做if(!IsPostBack)

protected void Page_Load(Object sender, EventArgs e)
{
    if(!Page.IsPostBack)
    {
        BindGridView();
    }
}

否则,您将加载旧值并阻止RowUpdated 事件。

更新

我可能做错了很多事情,你能告诉我我是怎么做的吗? 现在应该进行排序和更新吗?

这是一个完整的工作示例:

public partial class GridTest : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            BindGrid();
        }
    }

    private void BindGrid()
    {
        var source = GetCarTable().Select("", this.SortExpression).CopyToDataTable();
        GridCar.DataSource = source;
        GridCar.DataBind();
    }

    private string SortExpression
    {
        get
        {
            if (ViewState["SortExpression"] == null || string.IsNullOrEmpty((String)ViewState["SortExpression"]))
            {
                ViewState["SortExpression"] = "CarModel ASC";
            }
            return ViewState["SortExpression"].ToString();
        }
        set { ViewState["SortExpression"] = value; }
    }

    private static DataTable GetCarTable()
    {
        DataTable carsTable = new DataTable("cars");
        carsTable.Columns.Add("CarID");
        carsTable.Columns.Add("CarRegNum");
        carsTable.Columns.Add("CarModel");
        carsTable.Columns.Add("CarType");
        carsTable.Columns.Add("CarOwner");

        carsTable.Rows.Add(1, "AAA-111", "Toyota", "Hatchback", "Matti");
        carsTable.Rows.Add(2, "BBB-222", "Mercedes-Benz", "Van", "Keijo");
        carsTable.Rows.Add(3, "CCC-333", "Renault", "Regular", "Matilda");

        return carsTable;
    }

    protected void gridCar_Sorting(object sender, System.Web.UI.WebControls.GridViewSortEventArgs e)
    {
        string currentSortColumn = null;
        string currentSortDirection = null;
        currentSortColumn = this.SortExpression.Split(' ')[0];
        currentSortDirection = this.SortExpression.Split(' ')[1];

        if (e.SortExpression.Equals(currentSortColumn))
        {
            //switch sort direction
            switch (currentSortDirection.ToUpper())
            {
                case "ASC":
                    this.SortExpression = currentSortColumn + " DESC";
                    break;
                case "DESC":
                    this.SortExpression = currentSortColumn + " ASC";
                    break;
            }
        }
        else
        {
            this.SortExpression = e.SortExpression + " ASC";
        }

        //load the data with this SortExpression and DataBind the Grid
        BindGrid();
    }

    protected void GridCar_RowEditing(object sender, GridViewEditEventArgs e)
    {
        GridCar.EditIndex = e.NewEditIndex;
        BindGrid();
    }

    protected void GridCar_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
    {
        GridCar.EditIndex = -1;
        BindGrid();
    }

    protected void GridCar_RowUpdating(object sender, GridViewUpdateEventArgs e)
    {
        var oldValues = e.OldValues;
        var newValues = e.NewValues;
        // BindGrid();
    }

    protected void GridCar_RowUpdated(object sender, GridViewUpdatedEventArgs e)
    {
        //BindGrid();
    }
}

aspx 几乎保持不变:

<asp:GridView   ID="GridCar" 
            runat="server" 
            RowStyle-ForeColor="Black" 
            AllowSorting="true" 
            OnSorting="gridCar_Sorting" 
            AutoGenerateEditButton="true" 
            OnRowEditing="GridCar_RowEditing"
            OnRowCancelingEdit="GridCar_RowCancelingEdit"
            OnRowUpdating="GridCar_RowUpdating" 
            OnRowUpdated="GridCar_RowUpdated"
            AutoGenerateColumns="true">
</asp:GridView>

【讨论】:

  • 我用Page_Load 编辑了开头的帖子。我怀疑这是问题所在,因为我的排序工作非常好,尽管我确实必须为 e.SortDirection 构建一个解决方法,因为它总是升序。
  • 不要将DataTable 存储在 ViewState 中,这是不安全且非常低效的。您不需要传输表格,因为gridView 默认将其数据存储在 ViewState 中。我的回答仍然是,您必须将数据绑定包装在 !PostBack-check 中。
  • 我删除了我对 ViewState 所做的一切,并用我目前得到的内容再次编辑了原始帖子。不同的是,现在没有任何效果了。我无法对 GridView 进行排序,因为我试图在 gridCar_Sorting 中使用 gridCar.Sort 进行排序,这会导致堆栈溢出。我可能做错了很多事情,你能告诉我现在应该如何进行排序和更新吗?
  • 很好用!一个小的后续问题:我可以直接操作 GridView 中的数据,还是必须从它的 DataSource 中创建一个 DataTable,然后对其进行编辑并重新绑定?
  • 您可以在 GridView 中编辑数据,但是您必须更新 DataSource,在本例中为内存中的 DataTable。我认为这只是一个示例,而您实际上是在使用数据库。您要将数据存储在哪里?
【解决方案2】:

您的代码没有 DataSourceID。我假设数据绑定在代码后面。

如果您只想编辑/更新 GridView 的行,您需要的是 ItemUpdating 事件(例如 gridcar_ItemUpdating)而不是 RowUpdating。

希望对你有帮助。

【讨论】:

  • GridView 是否存在这些事件?我在&lt;asp:GridView&gt;&lt;/asp:GridView&gt; 找不到他们。
  • 哦,我的错。我以为是DetailsView。蒂姆的回答是解决您问题的更好方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-15
  • 1970-01-01
  • 2010-11-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多