亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Asp.net:如何添加引用動態創建元素的事件處理程序

Asp.net:如何添加引用動態創建元素的事件處理程序

C#
慕工程0101907 2021-06-30 21:10:02
我有一個 asp.net 程序,可以創建一個簡單的調查表供用戶回答。大多數問題使用一個下拉列表,其答案分數為 1-5(壞-好),我正在嘗試向下拉列表對象添加一個事件處理程序,以便僅在用戶選擇 1 到 1 之間的分數時才啟用評論框2.然而,當我為事件處理程序添加委托 lambda 調用時,而不是每個下拉列表影響它們自己對應的注釋框,它們似乎都只指向添加的最后一個(并且它們工作一次,然后沒有更多,只有最后一個 ddl 繼續具有預期的行為)。我的代碼:   //Called from Page_Load   private void PopulateSurvey()   {        btnSubmit.Enabled = true;        List<Question> questions = (from p in context.Questions                                    join q in context.Survey_Questions on p.ID equals q.QuestionID                                    where q.SurveyID == surveyid                                    select p).ToList();        Table tbl = new Table();        tbl.Width = Unit.Percentage(100);        TableRow tr;        TableCell tc;        TableCell tc1;        TableCell tc2;        TextBox txt;        CheckBox cbk;        DropDownList ddl = new DropDownList();        foreach (Question q in questions)        {            if (q.Division.Equals("General") || q.Division.Equals(ddlDivisions.SelectedValue.ToString()))            {                tr = new TableRow();                tc = new TableCell();                tc.Width = Unit.Percentage(55);                tc.Text = q.Text;                tc.Attributes.Add("id", q.ID.ToString());                tr.Cells.Add(tc);                tc = new TableCell();                if (q.QuestionType.ToLower() == "singlelinetextbox")                {                    txt = new TextBox();                    txt.ID = "txt_" + q.ID;                    //txt.Width = Unit.Percentage(40);                    tc.Controls.Add(txt);                }首先想到的是,事件處理程序可能會保留引用本身,而不是每個問題創建的孤立對象,因此所有事件處理程序最終都具有相同的 tc1 和 tc2 引用,因此只有最后一個對象?是這樣嗎,如果是這樣,我該如何解決?
查看完整描述

1 回答

?
搖曳的薔薇

TA貢獻1793條經驗 獲得超6個贊

你的問題在這一行:

ddl.SelectedIndexChanged +=
    (sender, e) => ScoreChanged(sender, e, tc1,tc2, ddl.SelectedIndex);

這里有兩件事很重要:

  • 您正在使用匿名方法調用ScoreChanged.

  • 您正在傳遞tc1tc2作為ScoreChanged方法的參數。您已在代碼塊的開頭、循環定義了這些變量。

在這種情況下,神奇的詞是閉包。由于tc1tc2是在匿名方法的范圍之外定義的,因此它們變成了閉包。這意味著在您定義方法時將沒有值,但在您調用它時。由于您不斷覆蓋foreach循環中變量的值,因此在調用時這些變量將具有循環最后一次迭代的值。

解決方案很簡單:在循環聲明變量。這將為 的每次迭代創建一個新的閉包foreach

TableRow tr;

TableCell tc;

TextBox txt;

CheckBox cbk;


foreach (Question q in questions)

{

    TableCell tc1;

    TableCell tc2;

    DropDownList ddl; //Don't forget to include ddl, since you are using its selected index

    //...

更一般的注意事項:不要在 C# 中的方法的開頭執行這樣的“聲明”塊。第一次使用時聲明變量(除非有充分的理由不這樣做,例如您希望它成為閉包的一部分)。這有很多很好的理由,而您只是體驗過其中的一個。另一種情況是,當您將部分代碼轉換為具有 Visual Studio 重構功能的方法時,您會將預先聲明的變量作為ref參數傳遞。這些是最明顯的原因。還有更多。


查看完整回答
反對 回復 2021-07-03
  • 1 回答
  • 0 關注
  • 146 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號