我在页脚中有一个带有 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
答案 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查询,但这在我的情况下不起作用。