2017-02-24 88 views
0

我有一個GridView與radiobuttonlist模板列和t extbox在頁腳。我希望單選按鈕在選定時立即更新,並使用本教程實現所需功能http://www.dotnetcurry.com/ShowArticle.aspx?ID=261。它效果很好。textbox顯示舊值後回發,而數據庫成功更新與新值

當腳本文本框中的新值發生更改時,SQL通過TextChanged()事件中的SqlDataSource Update()成功更新,但舊回值在回發後在文本框中返回。作爲支票,我將新的價值傳遞給頁面上的標籤,並且正確顯示。

我試圖把GridView1.DataBind()放在if(!IsPostBack)的Page_Load()中,但導致radiobuttonlist項目在更改時未保持選定狀態,而sqldatasource未更新。

我不知道這是相關的,但因爲這個應用程序是一個原型,所以當用戶在文本框中輸入MYID並點擊一個按鈕時,我正在加載頁面加載後的gridview中的特定記錄。最終,網格將通過來自另一個頁面的QueryString提供的值加載。

本質上我想讓文本框像radiobuttonlist一樣工作......只要值被更改我希望數據庫更新並在回發後在grid/textbx中顯示新值。有什麼明顯的我失蹤?

UPDDATE:加入RadioButtonList的SelectedIndexChanged事件代碼 更新2:加入的SqlDataSource UPDATE 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 &的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 [email protected]; " 
    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 

回答

0

我的解決方案包含在我更新的問題中。我的錯誤似乎一直在sqldatasource中放置2個更新查詢。我刪除了一個更新查詢,並創建了一個自定義方法來直接更新SQL數據庫,以便在textchanged事件和radiobuttonlist上立即更新文本框,以在selectedindexchanged時立即更新。我讀過你可以使用sqldatasource進行2次UPDATE查詢,如果你用分號分隔每個查詢,但是這在我的情況下不起作用。

0

您正嘗試更新數據庫並立即獲取更新值,但c#代碼不會等待SQL操作結束。請仔細閱讀本:

How to requery updated values immediately after update procedure runs

我建議你單獨升級改變文本框代碼。

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

謝謝@Farzin Kanzi花時間指引我走向正確的方向。我在週末閱讀了LINQ - 之前我從來沒有必要使用它。你能告訴我爲什麼在回發時立即在UI/gridview中顯示radiobuttonlist的更新,但是當兩個事件的代碼幾乎完全相同時,不會顯示在文本框中?我更新了我的問題,以包含radiobuttonlist selectedindexchanged事件代碼。 – Doreen

+0

現在我懷疑我的回答!請告訴我這是什麼:文本框中的Text ='Section 1 Comments'? –

+0

有趣的你應該問,只是他的早晨,我改變了文本屬性爲Text ='<%#Bind(「Comment1」)%>'然而即使在page_Load上,數據庫值也沒有填充文本框。我認爲問題在於SQL查詢。用於填充網格的select語句是2個表的連接,如果存在單獨的列,查詢結果將顯示網格中每個項的註釋字段。我只想讓它出現一次,這就是爲什麼我把它放在頁腳中,但我認爲這可能是它爲什麼會行爲不端。我想知道我是否需要一個單獨的sqldatasource僅用於文本框? – Doreen