【问题标题】:Data Going Out of Synch when using GridView inside UpdatePanel在 UpdatePanel 中使用 GridView 时数据不同步
【发布时间】:2019-04-25 14:06:16
【问题描述】:

UpdatePanel 内的 GridView 中的数据与数据库不同步,我不知道为什么。这导致数据库更新不正确,我必须迅速修复!任何人都可以帮忙吗?

我有多个 UpdatePanel,其中包含用户可以编辑的 GridView。有一个搜索功能和过滤按钮,可以从数据库中选择查询的数据并显示在 GridView 中。启用了排序,并且“不同步”主要发生在排序然后编辑字段时。

数据来自 SQL 数据库。我可以通过我的 TemplateField 的 OnTextChange 选项直接更新数据,如下所示:

<asp:GridView 
    ID="GridView4" 
    runat="server" 
    OnSorting="TaskGridView_Sorting" 
    AllowSorting="True" 
    Width="100%" >
    <Columns>
    <asp:TemplateField SortExpression="name" HeaderText="Name">
    <HeaderStyle HorizontalAlign="Left" CssClass="col_name" />
    <ItemTemplate>
        <asp:TextBox ID="name" AutoPostBack="True" CssClass="col_name" runat="server" Text='<%# Eval("name") %>' Width=180 OnTextChanged="text_change" />
    </ItemTemplate>                 
    </asp:TemplateField> 
    ...

我的网格视图位于具有以下选项的 UpdatePanel 中:

    <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
        <ContentTemplate>
         ...

我已经启用了这样的部分渲染:

    <ajaxToolKit:ToolkitScriptManager EnablePartialRendering="true" runat="server" />

我有一些按钮,通过重新查询数据库并仅显示过滤后的数据来过滤数据,如下所示:

DataGrid_Load(DAL.Search_reg_log(OrgText.Text, searchText, searchCol), "reg");

gridview 像这样加载它的数据:

private void DataGrid_Load(DataTable command, string type)
{   
    DataTable dataTable = new DataTable();
    dataTable = command;
    string sortDir = ViewState["SortDirection"] as string;
    string sortExp = ViewState["SortExpression"] as string;

    if(ViewState["SortExpression"] != null)
    {                   
        dataTable = resort(dataTable, sortExp, sortDir);
    }

    try 
    {
        var query = from c in dataTable.AsEnumerable() 
                   where c.Field<string>("status") == "Invoiced" && c.Field<string>("reg_cat_id") != "Archive"
                      || c.Field<string>("status") == "Confirmed" && c.Field<string>("reg_cat_id") != "Archive" 
                  select c ;    

        if(query.Any()){
            DataTable t2 = query.CopyToDataTable();
            GridView4.DataSource = t2;
            GridView4.DataBind();
        } else {
            GridView4.DataSource = new DataTable();
            GridView4.DataBind();
        }
    }           
    catch(Exception e) {
        ErrorText.Text = "Caught Exception: " + e;              
    }

...

我已经隔离了一个导致数据错误的原因,该错误是在对列进行排序后发生的,然后

protected void TaskGridView_Sorting(object sender, GridViewSortEventArgs e)
{               
    string sortExp = ViewState["SortExpression"] as string;     
    string sortDir = ViewState["SortDirection"] as string;
    if(sortDir == "asc" & sortExp == e.SortExpression.ToString())
        ViewState["SortDirection"] = "desc";
    else
        ViewState["SortDirection"] = "asc";
    ViewState["SortExpression"] = e.SortExpression.ToString();

    if(searchCol != "" && searchText != "")
        DataGrid_Load(DAL.Search_reg_log(OrgText.Text, searchText, searchCol), "reg");
    else
        DataGrid_Load(DAL.reg_log(HeadText.Text, OrgText.Text), "reg");     

    UpdatePanels();

}

这里是度假村功能:

public static DataTable resort(DataTable dt, string colName, string direction)
{
    dt.DefaultView.Sort = colName + " " + direction;
    dt = dt.DefaultView.ToTable();
    return dt;
}

请就可能导致此问题的一些方向提供帮助。

【问题讨论】:

  • 有人对赏金感兴趣吗?

标签: asp.net gridview updatepanel


【解决方案1】:

看起来您在使用 GridView 和更新它们时遇到了一些问题。我将在下面发布一个完整的工作示例。从那开始并逐渐更新代码以满足您自己的需求,例如使用var query = from c in dataTable.AsEnumerable() 获取数据。重要的是每次(重新)绑定 GridView 数据时对数据进行排序。而且我不确定resort 内部发生了什么,但您必须使用dt.DefaultView.ToTable(); 将排序保存在DataTable 中。

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
    <ContentTemplate>

        <asp:GridView ID="GridView1" runat="server"
            DataKeyNames="ID" AllowSorting="true" 
            OnSorting="GridView1_Sorting"
            AutoGenerateColumns="false" 
            AutoGenerateEditButton="true"
            OnRowEditing="GridView1_RowEditing"
            OnRowCancelingEdit="GridView1_RowCancelingEdit"
            OnRowUpdating="GridView1_RowUpdating">
            <Columns>

                <asp:TemplateField HeaderText="ID" SortExpression="ID">
                    <ItemTemplate>
                        <%# Eval("ID") %>
                    </ItemTemplate>
                </asp:TemplateField>

                <asp:TemplateField HeaderText="Name" SortExpression="name">
                    <ItemTemplate>
                        <%# Eval("name") %>
                    </ItemTemplate>
                    <EditItemTemplate>
                        <asp:TextBox ID="TextBox1" runat="server" Text=' <%# Eval("name") %>'></asp:TextBox>
                    </EditItemTemplate>
                </asp:TemplateField>

            </Columns>
        </asp:GridView>

        <asp:Literal ID="Literal1" runat="server"></asp:Literal>

    </ContentTemplate>
</asp:UpdatePanel>

后面的代码

protected void Page_Load(object sender, EventArgs e)
{
    //bind data in an ispostback check
    if (!IsPostBack)
    {
        DataGrid_Load();
    }
}


private void DataGrid_Load()
{
    //load the datatable data
    DataTable dt = source;

    //check if the viewsstate existst
    if (ViewState["SortExpression"] != null && ViewState["SortDirection"] != null)
    {
        //sort the datatable before binding it to the gridview
        dt.DefaultView.Sort = ViewState["SortExpression"] + " " + ViewState["SortDirection"];
        dt.DefaultView.ToTable();
    }

    //bind the sorted datatable to the gridvidw
    GridView1.DataSource = dt;
    GridView1.DataBind();
}


protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
    //load the previous sorting settigns
    string sortExp = ViewState["SortExpression"] as string;
    string sortDir = ViewState["SortDirection"] as string;

    //reverse the direction if the column is the same as the previous sort
    if (sortDir == "asc" & sortExp == e.SortExpression.ToString())
        ViewState["SortDirection"] = "desc";
    else
        ViewState["SortDirection"] = "asc";

    //put the current sort column in the viewstate
    ViewState["SortExpression"] = e.SortExpression.ToString();

    //rebind data
    DataGrid_Load();
}


protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
    //set the edit index and rebind data
    GridView1.EditIndex = e.NewEditIndex;
    DataGrid_Load();
}


protected void GridView1_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
    //reset the edit index and rebind data
    GridView1.EditIndex = -1;
    DataGrid_Load();
}


protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
    //use findcontrol to locate the textbox in the edit template
    TextBox tb = (TextBox)GridView1.Rows[e.RowIndex].FindControl("TextBox1");

    //get the id of the row from the datakeys
    int id = Convert.ToInt32(GridView1.DataKeys[e.RowIndex].Values[0]);

    //show result for testing
    Literal1.Text = "ID: " + id + "<br>Name: " + tb.Text;

    //reset the edit index and rebind data
    GridView1_RowCancelingEdit(null, null);
}

【讨论】:

  • 感谢您的详细回答。如果我有几个网格视图,我从 DataGrid_Load 函数中加载所有这些视图是否正确?还是应该各自有一个单独的加载函数?
  • 最好单独加载,这样可以节省一些开销。根据您获取数据的方式,它可以节省一些数据库查询。
  • 好的,最好是单独的dataGrid1_Load、dataGrid2_Load l等
  • 是的,如果需要,您也可以从其他地方调用该方法。
  • 如果您没有在OnTextChanged="text_change" 事件中将更新后的数据重新绑定到网格视图,则可能是问题所在。尽管文本框和数据库中的值发生了变化,但页面可能会保留 ViewState 中的旧值。这将恢复到页面,而不是新值。
猜你喜欢
  • 2012-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-08
  • 2011-06-15
  • 1970-01-01
  • 2010-09-29
  • 1970-01-01
相关资源
最近更新 更多