我有一個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
謝謝@Farzin Kanzi花時間指引我走向正確的方向。我在週末閱讀了LINQ - 之前我從來沒有必要使用它。你能告訴我爲什麼在回發時立即在UI/gridview中顯示radiobuttonlist的更新,但是當兩個事件的代碼幾乎完全相同時,不會顯示在文本框中?我更新了我的問題,以包含radiobuttonlist selectedindexchanged事件代碼。 – Doreen
現在我懷疑我的回答!請告訴我這是什麼:文本框中的Text ='Section 1 Comments'? –
有趣的你應該問,只是他的早晨,我改變了文本屬性爲Text ='<%#Bind(「Comment1」)%>'然而即使在page_Load上,數據庫值也沒有填充文本框。我認爲問題在於SQL查詢。用於填充網格的select語句是2個表的連接,如果存在單獨的列,查詢結果將顯示網格中每個項的註釋字段。我只想讓它出現一次,這就是爲什麼我把它放在頁腳中,但我認爲這可能是它爲什麼會行爲不端。我想知道我是否需要一個單獨的sqldatasource僅用於文本框? – Doreen