文本框在回发后显示旧值,而数据库使用新值成功更新

时间:2017-02-24 23:09:41

标签: c# asp.net gridview textbox sqldatasource

我在页脚中有一个带有 radiobuttonlist 模板列和t extbox 的GridView。我希望单选按钮在选中时立即更新,并使用本教程来实现所需的功能http://www.dotnetcurry.com/ShowArticle.aspx?ID=261。它很棒。

当更改页脚文本框中的新值时,通过TextChanged()事件中的SqlDataSource Update()成功更新SQL,但是在回发后返回文本框中的旧值。作为检查,我将新值传递给页面上的标签,并且也正确显示。

我尝试将GridView1.DataBind()放在if(!IsPostBack)的Page_Load()中,但这会导致radiobuttonlist项目在更改时不会保持选中状态且sqldatasource未更新。

我不知道这是否相关但是因为这个应用程序是一个原型,我正在加载页面加载后的gridview中的特定记录,当用户在文本框中输入MYID并单击按钮时。最终,网格将加载来自另一个页面的QueryString提供的值。

基本上我希望文本框像radiobuttonlist一样工作......一旦值改变,我希望数据库更新并在回发后显示grid / textbx中的新值。有什么东西显而易见吗?

UPDDATE :添加了radiobuttonlist selectedindexchanged事件代码 更新2:添加了sqldatasource 更新3:解决方案是直接通过自定义方法更新SQL数据库,删除sqldatasource中的第二个更新查询。更新了TextChanged事件代码并添加了自定义方法。

HTML:

<asp:GridView ID="GridView1" runat="server" 
        AutoGenerateColumns="False" 
        DataKeyNames="MYID" 
        DataSourceID="SqlDataSource1" 
        onrowdatabound="GridView1_RowDataBound" 
        ShowFooter="True" > 
        <Columns> 
<asp:BoundField DataField="MYID" HeaderText="MYID" ReadOnly="True" 
                SortExpression="MYID" /> 
            <asp:BoundField DataField="DocID" HeaderText="DocID" ReadOnly="True" 
                SortExpression="DocID" />
            <asp:BoundField DataField="ItemID" HeaderText="ItemID" 
                InsertVisible="False" ReadOnly="True" SortExpression="ItemID" />
            <asp:TemplateField HeaderText="Item" SortExpression="Item">
                <ItemTemplate>
                    <asp:Label ID="Label1" runat="server" Text='<%# Bind("Item") %>'></asp:Label>
                </ItemTemplate>
                <FooterTemplate > 
               <asp:TextBox ID="txtComment1" runat="server" 
                    Text='Section 1 Comments' AutoPostBack="True" 
                    ontextchanged="txtComment1_TextChanged" MaxLength="1000" 
                    TextMode="MultiLine" Width="650px"></asp:TextBox> 
            </FooterTemplate>
            </asp:TemplateField>
                <asp:TemplateField HeaderText=" -- 1 -- 2 -- 3 -- 4 -- 5 -- " >     
                    <ItemTemplate>
                <asp:RadioButtonList AutoPostBack="True" ID="rblRating" runat="server"
                    Enabled="true" SelectedIndex='<%#Convert.ToInt32(DataBinder.Eval(Container.DataItem , "Rating"))%>' 
                    OnSelectedIndexChanged="rblRating_SelectedIndexChanged" RepeatDirection="Horizontal">
                    <asp:ListItem Value="0">0</asp:ListItem>
                    <asp:ListItem Value="1">1</asp:ListItem>
                    <asp:ListItem Value="2">2</asp:ListItem>
                    <asp:ListItem Value="3">3</asp:ListItem>
                    <asp:ListItem Value="4">4</asp:ListItem>
                    <asp:ListItem Value="5">5</asp:ListItem>                        
                </asp:RadioButtonList>
            </ItemTemplate>

        </asp:TemplateField>
            <asp:BoundField DataField="Rating" HeaderText="Rating" 
                SortExpression="Rating" ReadOnly="True" />
        </Columns>
    </asp:GridView>
        <asp:Label ID="lblComments1" runat="server" Text="Label"></asp:Label>
    </div>

.CS:

protected void UpdateComment1(int myid, string comment)
        {                                                
            using (SqlConnection con = new SqlConnection(conStr)))
        { 
        string cmdStr = "UPDATE tblComments SET Comment1 = @Comment1 WHERE MYID = @MYID";

                using (SqlCommand cmd = new SqlCommand(cmdStr, con)))
                {  
                cmd.Parameters.AddWithValue("@MYID", myid);
                cmd.Parameters.AddWithValue("@Comment1", comment);
                try
                {
                    con.Open();
                    int affectedRows = cmd.ExecuteNonQuery();
                }
                catch (SqlException ex)
                {
                    Response.Write(ex.Message);
                }
        }
       }
        }
protected void txtComment1_TextChanged(object sender, EventArgs e)
        {
            TextBox tbox = (TextBox)sender;
            string oldComment1 = ViewState["OldComment1"].ToString(); //value saved from PreRender()
            string newComment1 = (GridView1.FooterRow.FindControl("txtComment1") as TextBox).Text;
            ViewState["Section1Comments"] = newComment1;

                if(oldComment1 != newComment1)
                {
                    //<<TODO>>update history table 
                }

            if (newComment1 != null)
            {   
             //update SQL directly via custom method                  
              UpdateComment1(Convert.ToInt32(MYID), newComment1);  
            }
            GridView1.DataBind(); 
        }

 protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            DataRowView drv = e.Row.DataItem as DataRowView;
            RadioButtonList rbtnl = (RadioButtonList)e.Row.FindControl("rblRating");

            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                if ((e.Row.RowState & DataControlRowState.Normal) > 0) //.Edit, .Normal, .Alternate, .Selected
                {
             //check for null
                    if (rbtnl.SelectedItem != null)
                    {
                        if (rbtnl.SelectedItem.Text == "0") //if rating isn’t inserted into SQL yet, deselect all 5 radio buttons
                        {
                            rbtnl.SelectedItem.Selected = false;
                        }
                            rbtnl.SelectedValue = drv[4].ToString();
                    }
                }

                //remove extra list item 
                ListItem blank = rbtnl.Items.FindByValue("0");
                if (blank != null)
                {
                    rbtnl.Items.Remove(blank);//always remove list item at index zero
                }
            }
        }

protected void rblRating_SelectedIndexChanged(object sender, EventArgs e)
        {
            string rate = string.Empty;

            RadioButtonList rBtnList = (RadioButtonList)sender;
            GridViewRow gvr = (GridViewRow)rBtnList.Parent.Parent;

            if (rBtnList.SelectedValue != null)
            {
                rate = rBtnList.SelectedValue;

                SqlDataSource1.UpdateParameters["Rating"].DefaultValue = rate;
                SqlDataSource1.UpdateParameters["MYID"].DefaultValue = gvr.Cells[0].Text;
                SqlDataSource1.UpdateParameters["ItemID"].DefaultValue = gvr.Cells[2].Text;
            }
            else
            {     
            }  
            SqlDataSource1.Update(); 
            GridView1.DataBind();
        }

SQL&amp;的SqlDataSource:

    <asp:SqlDataSource 
    ID="SqlDataSource1" 
    runat="server" 
    ConnectionString="<%$ ConnectionStrings:SomeConnectionString %>" 
    SelectCommand="SelectSection1" 
    UpdateCommand="UPDATE tblDetails SET Rating = @Rating WHERE MYID =  @myid   AND ItemID = @ItemID;
    --UPDATE [tblComments]  SET [Comment1] = @Comment1 WHERE MYID =@myid; " 
    SelectCommandType="StoredProcedure" >
        <SelectParameters>
            <asp:ControlParameter ControlID="TextBox1" DefaultValue="0"              Name="eprid"  PropertyName="Text" Type="Int32" />
        </SelectParameters>
        <UpdateParameters> 
            <asp:Parameter Name="Rating" Type="Int32" /> 
            <asp:Parameter Name="myid" Type="Int32" /> 
            <asp:Parameter Name="ItemID" Type="Int32" /> 
            <asp:Parameter Name="Comment1" Type="String" />
            </UpdateParameters> 
</asp:SqlDataSource>

ALTER PROCEDURE [dbo].[SelectSection1] 
    @myid int  
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

--Has Form been submitted to tblComments yet?
declare @docid int
set @docid =(select distinct d.docid    
    from dbo.tblEmployee  e 
    full outer join dbo.tblDetails d on e.MYID = d.myid
    where e.myid = @myid)

 IF  @docid is null

----if not submitted yet, fill grid with evaluation items only, set rating to NULL
 BEGIN 
 SELECT 
      @myid As MYID
      ,0 as DocID
      ,ItemID 
      ,Item
      ,0 as Rating 
      ,'' As Comment1

  FROM [EPR].[dbo].[tblItems] 

  where SectionID = 1 and Active = 1  


  END
-- if submitted (DocID exists), fill grid with evaluations items and rating
 ELSE 
  BEGIN
  SELECT  
         d.eprid   
        ,d.DocID 
        ,i.[ItemID] 
        ,i.[Item] 
        ,d.Rating
        ,c.Comment1 

  FROM [EPR].[dbo].[tblItems] i

  join tblDetails  d on i.ItemID  = d.ItemID 
  join tblComments c on  d.MYID = c.MYID

  --Competence Section  
  where i.SectionID = 1 and i.Active = 1  and d.MYID = @myid 

  END
END

2 个答案:

答案 0 :(得分:0)

您正在尝试更新数据库并立即获取更新值,但c#代码不会等到SQL操作结束。请阅读:

How to requery updated values immediately after update procedure runs

我建议您分别更新已更改的文本框代码。

//after all things done:
theTextbox.Text = the_value_that_it_sended.

答案 1 :(得分:0)

我的解决方案包含在我更新的问题中。我的错误似乎是在sqldatasource中放置了2个更新查询。我删除了一个更新查询,并创建了一个自定义方法来直接更新SQL数据库,以便在textchanged事件和radiobuttonlist上立即更新文本框,以便在selectedindexchanged时立即更新。我读到如果用分号分隔每个查询,你可以使用sqldatasource进行2次UPDATE查询,但这在我的情况下不起作用。