ASP.NET Repeater遍历仅返回第一项/默认值问题求助
你遇到的问题是典型的ASP.NET回发时控件状态被重置的情况,核心原因是:你在页面的Page_Load事件中没有判断IsPostBack,导致每次回发(比如点击按钮)时都会重新绑定Repeater,从而覆盖用户在DropDownList中选择的值。
解决步骤
1. 修改Repeater的绑定逻辑,仅在首次加载时执行
打开你的页面后台代码,找到Page_Load方法,确保Repeater的数据绑定只在页面首次加载(非回发)时执行,代码示例如下:
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { // 这里写你绑定Repeater1的代码,比如: // Repeater1.DataSource = 你的数据源; // Repeater1.DataBind(); } }
这样一来,当用户点击按钮触发回发时,Repeater不会被重新绑定,控件的ViewState会保留用户选择的DropDownList值,你就能正确获取到选中值了。
2. 验证你的Repeater1_ItemDataBound方法
如果你的Repeater1_ItemDataBound方法里有给DropDownListadet绑定选项的逻辑,不用额外修改——只要Repeater只在非回发时绑定,这个方法也只会在首次加载时触发,不会覆盖用户的选择。
3. 优化按钮点击方法(可选但推荐)
你的Button2_Click1方法里有重复遍历Repeater的冗余代码,同时存在SQL注入风险,建议改用参数化查询优化,示例如下:
protected void Button2_Click1(object sender, EventArgs e) { foreach (RepeaterItem ri in Repeater1.Items) { if (ri.ItemType == ListItemType.Item || ri.ItemType == ListItemType.AlternatingItem) { DropDownList ddladet = ri.FindControl("DropDownListadet") as DropDownList; DropDownList ddlmf = ri.FindControl("DropDownListmf") as DropDownList; Label lblfiyat = ri.FindControl("Labelfiyat") as Label; Label Labelkar = ri.FindControl("Labelkar") as Label; Label Labeladı = ri.FindControl("Labeladı") as Label; Label LabelID = ri.FindControl("LabelID") as Label; // 先判断用户是否选择了有效选项 if (ddladet.SelectedValue != "0" && ddlmf.SelectedValue != "0") { double birimfiyat = ((Convert.ToDouble(lblfiyat.Text)) / ((Convert.ToDouble(Labelkar.Text) / 100) + 1)) * (Convert.ToDouble(ddladet.SelectedValue)) / (Convert.ToDouble(ddlmf.SelectedValue) + Convert.ToDouble(ddladet.SelectedValue)); birimfiyat = Math.Round(birimfiyat, 3); // 使用参数化查询避免SQL注入 using (SqlConnection conn = new SqlConnection(SqlC.con.ConnectionString)) { conn.Open(); string sql = @"INSERT INTO SiparişTemP3( tip, UrunAdıID, UrunADI, Adet, MalfazlasıAdet, Toplam, BirimFiyat, SatışFiyat, KullanıcıID,EczaneID) VALUES( '0', @UrunAdıID, @UrunADI, @Adet, @MalfazlasıAdet, @Toplam, @BirimFiyat, @SatışFiyat, @KullanıcıID, @EczaneID)"; SqlCommand cmd = new SqlCommand(sql, conn); cmd.Parameters.AddWithValue("@UrunAdıID", LabelID.Text); cmd.Parameters.AddWithValue("@UrunADI", Labeladı.Text); cmd.Parameters.AddWithValue("@Adet", ddladet.SelectedValue); cmd.Parameters.AddWithValue("@MalfazlasıAdet", ddlmf.SelectedValue); cmd.Parameters.AddWithValue("@Toplam", Convert.ToInt32(ddladet.SelectedValue) + Convert.ToInt32(ddlmf.SelectedValue)); cmd.Parameters.AddWithValue("@BirimFiyat", birimfiyat); cmd.Parameters.AddWithValue("@SatışFiyat", Convert.ToDouble(lblfiyat.Text.Replace(",", "."))); cmd.Parameters.AddWithValue("@KullanıcıID", KullanıcıID()); cmd.Parameters.AddWithValue("@EczaneID", EczaneID); cmd.ExecuteNonQuery(); } } } } // 绑定Repeater2的逻辑同样改用参数化查询 using (SqlConnection conn = new SqlConnection(SqlC.con.ConnectionString)) { conn.Open(); string sql = @"SELECT SiparisID,EczaneID, UrunADI, Adet, MalfazlasıAdet,Toplam,BirimFiyat,SatışFiyat FROM SiparişTemP3 WHERE KullanıcıID = @KullanıcıID"; SqlCommand cmd12 = new SqlCommand(sql, conn); cmd12.Parameters.AddWithValue("@KullanıcıID", KullanıcıID()); SqlDataAdapter sda21 = new SqlDataAdapter(cmd12); DataTable dt112 = new DataTable(); sda21.Fill(dt112); Repeater2.DataSource = dt112; Repeater2.DataBind(); } }
问题原理说明
ASP.NET的页面生命周期中,回发时会先执行Page_Load,再执行按钮的点击事件。如果你的Page_Load里每次都绑定Repeater,那么在点击事件执行前,Repeater已经被重新渲染,DropDownList会回到默认状态,所以你获取到的永远是默认值。加上!IsPostBack判断后,只有首次加载页面时才绑定Repeater,回发时会保留控件的ViewState,用户的选择就不会丢失了。
内容的提问来源于stack exchange,提问作者MEHMET RECAİ BOZKIR

