2012-04-16 54 views
2

在Web表單我動態創建一系列chekboxes的被添加到一個asp:佔位如何從一個動態生成的複選框列表獲取複選框的值在asp.net

//Generates the List of Entities that may be shared 
     protected void GenerateEntityList(string agencyId, string agencyName) 
     { 
      var selectedAgency = UserFactory.GetAgencyAndSharedDataById(Convert.ToInt64(agencyId)); 

      entityContainer.Controls.Clear(); 

      //builds the entity list based upon entities in DB 
      var currentEntities = UserFactory.GetEntityList(); 
      //add checkboxes 
      entityContainer.Controls.Add(new LiteralControl("<input type='checkbox' id='selectAllCB' value='All'>Select All<br/><br/>")); 
      foreach (var item in currentEntities) 
      { 
       CheckBox entityCheckBox = new CheckBox(); 
       int currentItem = item.EntityTypeId.GetValueOrDefault(0); 
       entityCheckBox.Text = item.EntityName.ToString(); 

       entityCheckBox.CssClass = "am_Checkbox"; 
       entityContainer.Controls.Add(entityCheckBox); 
       entityContainer.Controls.Add(new LiteralControl("<br/><br/>")); 

       //mark checkboxes as checked if currently stored in the database 
       if (selectedAgency.FirstOrDefault().SecurityDataShares != null && selectedAgency.FirstOrDefault().SecurityDataShares.Count > 0) 
       { 
        foreach (var ce in selectedAgency.FirstOrDefault().SecurityDataShares) 
        { 
         if (ce.EntityId == item.EntityId) 
         { 
          entityCheckBox.Checked = true; 
         } 
        } 
       } 
      } 

一旦創建的用戶有能力製作或刪除選擇。點擊更新時,我想返回/收集複選框中的值,以便我可以將它們插入到數據庫中。

//get the text value of every checkbox 
protected void updateEnties() 
{ 
    string receivingAgency = ReceivingAgencyID; 
    long contributingAgency = QueryID; 

    List<string> cbValues = new List<string>(); 
    foreach (CheckBox currentItem in entityContainer.Controls) 
    { 
     cbValues.Add(currentItem.Text); 
    } 
} 

然而,當我試圖遍歷我沒有得到任何東西收集這使我相信,無論是我錯誤地調用控件或它正在因回傳被破壞。 而不是將這些元素寫入佔位符應該使用另一個控件,如Listbox控件?

有人可以請我提供一些關於如何檢索複選框值的指導嗎?

回答

4

有兩種思想流派;一,您需要重新創建初始視圖的控制層次結構,以便頁面可以將視圖狀態和表單值恢復到控制樹中,或者兩個,您可以使用低科技解決方案並簡單地獲取來自表單集合的值。

我個人喜歡選項2,處理起來相對容易,而且看起來您已經手動創建了帶有LiteralControl的HTML。只需提供被你手動創建的輸入標籤之間共享的name屬性(例如這裏爲簡便起見顯示,這可能不是你會做什麼):

entityContainer.Controls.Add(new LiteralControl("<input type='checkbox' name='mySharedName' />"); 

然後,爲了得到它是這麼簡單的值:

var selectedValues = Request.Form["mySharedName"]; 
// This is now a comma separated list of values that was checked 

然後你不必擔心控制樹的狀態。

+0

這似乎工作正常,但要求。Form只返回所選表單元素的「on」值任何有關如何獲取值的建議?檢查示例複選框foo如何獲取'var selectedValues'以顯示數組中的foo與 – rlcrews 2012-04-16 20:51:00

+0

淘汰過程。對於Z項目,如果您知道X被選中,則不檢查(Z - X)。但是當你只想知道檢查了哪些項目時,這個過程會更好。 – Tejs 2012-04-16 21:19:48

+0

啊,這是我的問題。我的列表是使用linq動態生成的,並且按字母順序排序不一定是如何將它存儲在數據庫或固定值中我真的需要導出這兩個數據,以便我可以交叉引用以確保捕獲正確的選中元素 – rlcrews 2012-04-16 21:32:01

-1

這是你應該使用面向對象的原則來實現一個實現的東西。在這種情況下,你應該建立你自己的CheckBoxCollection(從適當的接口/類繼承)。它將簡化代碼並使其更加劃分和可擴展。

其中一個實現細節然後處理您描述的情況:拋入一個點擊處理程序,它將添加到viewstate/session /任何內容,並且您應該能夠看到您的測試用具/用戶在一目瞭然。

另一個快速點:你不應該使用< br/>標籤佈局了,特別是如果你已經在使用CSS。您可以確保checkboxen是您需要的任何顯示類型(在本例中爲block),然後將其設置在您已經裝飾了該控件的CSS類中。 dr:我沒有時間在代碼中拋出一個例子,但基本思想是你應該有一個CheckBoxCollection()(根據你的喜好)保留它的CheckBox()s'。檢查從行動到行動的狀態。

+0

-1:沒有冒犯,但這聽起來像是主要的矯枉過正。 – 2012-04-16 20:03:28

+0

感謝您對'
'標記的建議,我刪除了它們並更新了CSS以支持佈局。你的建議比我所需要的要多,因爲我不想使用點擊處理程序檢查和更新每次點擊的視圖狀態/會話。 – rlcrews 2012-04-16 20:18:36

+0

@JamesJohnson事實並非如此 - 這是做到這一點的「正確」方式。部分原因是我們的職業有時會產生像我這樣的痛苦的人,更多的人只是扔垃圾代碼,並將其永遠留在生產中。 一個適當考慮的解決方案是一個快樂的解決方案。特別是當你定製了一些東西的時候,當事情被抽象出來的時候,用各種方式進行管理更容易。 很高興你看到適合downvote我的答案沒有實際反駁它以某種方式;你很成熟。 – Tonweight 2012-04-17 20:48:49

2

這聽起來像你可以使用CheckBoxList取而代之,讓你的生活更輕鬆,並將你的結果集綁定到它。這實際上將消除對任何動態內容的需求。

<asp:CheckBoxList ID="CheckList1" runat="server" DataTextField="TextColumn" DataValueField="ValueColumn" ...> 

如果這不是一個選項,那麼您需要在每次回發後重新創建控件。有幾種方法可以做到這一點。

最簡單的辦法

退房的DynamicControlsPlaceHolder控制。這是一個有用的小控件,用於處理幕後持久動態內容。我會建議這個選項,因爲它從動態創建的內容中消除了所有的痛苦。

手動方式

重新創建期間OnInit控制(一個或多個)。只要確保你指定同一個ID的控制,這樣的ViewState可以重新填充的選擇:

protected override void OnInit(EventArgs e) 
{ 
    var chk = new CheckBox { ID = "chkBox1" };     
    PlaceHolder1.Controls.Add(chk); 

    base.OnInit(e); 
}  

回發後重新創建控件後,你應該能夠訪問這樣的價值觀:

foreach (CheckBox chk in PlaceHolder1.Controls.OfType<CheckBox>()) 
{ 
    if (chk.Checked) 
    { 

    }  
} 
+0

對不起,我錯過了這裏的東西,看起來非常直接,但foreach會在我的點擊事件的方法中正確嗎?所以讓我遍歷列表?是上面的foreach應該嵌套在另一個foreach語句中。我要求上面的代碼引用一個具有選定屬性的對象項目? – rlcrews 2012-04-16 21:02:50

+0

對不起,忘了更新那部分的例子。應該是chk.Checked。我最初的例子是使用CheckBoxList。我更新了我的更新,所以現在應該更清楚:) – 2012-04-16 21:11:07

0

感謝大家的建議。基於如何實施這個方案,我將Tejs的答案記入Tejs,因爲他將這個解決方案的思路推到了我的頭上。在這個項目中,我需要使用複選框與複選框列表控件,因爲我是如何構建列表並驗證已檢查的元素的。挑戰來自於asp.net如何生成複選框控件以及它允許​​向控件插入屬性的限制(名稱,值等)

因此,要從代碼生成的複選框中捕獲值,我做了以下:

內aspx文件我增加了一個隱藏的輸入字段,並分配中用runat = server的標籤

<input id="cbEntityList" type="hidden" runat="server" value="" /> 

TEJS解決方案是相似的,但我不喜歡加入一個隱藏字段爲理念每個複選框都像是頁面中的很多元素。

然後,我修改了複選框代碼生成片段,以包含來自我的對象的唯一標識符作爲Id。 ID獲取的HTML作爲name屬性呈現出來所以這讓我怎麼有東西,我可以用JavaScript檢索/ jQuery的

所以foreach語句,我將建立的複選框中添加以下行

entityCheckBox.ID = item.EntityId.ToString(); 

最後,我用jQuery來迭代複選框的頁面,並返回一個只有選中項目的字符串數組。

這將基於選中的複選框將填充回隱藏字段的值(0,1,2,3,4)。

$('#btnUpdateEntities').click(function (event) { 
     var fields; 
     $(':checkbox:checked').each(function() { 
      var txt = $("input[name='cbEntityList']"); 

      fields = ($(':checkbox:checked').map(function() { 
       return this.name; 
      }).get().join(",")); 

      $(txt).val(fields); 
     }); 
    }); 

然後我可以訪問值的數組在我後面的代碼爲:

string voo = cbEntityList.Value; 

希望這有助於任何興趣。