在UpdatePanel中使用GridView时数据不同步

时间:2018-11-22 22:18:26

标签: asp.net gridview updatepanel

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

我有多个UpdatePanels,这些UpdatePanels内部具有GridViews,用户可以对其进行编辑。有一个搜索功能和过滤器按钮,它们从数据库中选择查询的数据并显示在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中拥有gridview:

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

请帮助您指导可能的原因。

1 个答案:

答案 0 :(得分:3)

您似乎在使用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);
}