2009-12-29 31 views
3

對於冗長的帖子,事先道歉,但我在建立一個.NET頁面時遇到了一些麻煩。閱讀頁面回傳的動態複選框的'已檢查'屬性

END問題:如何在Page_Load子例程中檢查動態創建的複選框的「Checked」屬性?

詳細信息:基本上,我有一個VB.NET頁面,根據用戶選擇的數字動態創建一些表格行。因此,例如,如果用戶從下拉列表中選擇「3」,則頁面回傳並創建三個表格行。每行都包含幾個文本框,一個下拉列表和一個複選框(這些都是.NET表單控件,而不是純HTML控件,我應該指出)。

通常,用戶會在窗體控件中輸入一些細節,然後單擊「提交」按鈕,之後頁面遍歷每一行,並將數據插入到SQL Server表中。

但是,如果用戶勾選該行的複選框,則表示該頁面將忽略該行,並且在用戶單擊「提交」時不將該行數據插入數據庫。

這很好,但有一個問題。如果用戶點擊「提交」並且一些輸入到表單控件的值是無效的(例如,用戶沒有輸入他們的名字),那麼頁面將不提交數據,而是顯示錯誤向用戶通知他們需要改變的值。但是,例如,如果用戶創建三行,但決定「忽略」第三行(通過勾選複選框),然後當頁面回傳,找到一些無效條目,並重新向用戶顯示錶單以允許它們爲了糾正任何錯誤,我寧願頁面沒有完全渲染第三行。畢竟,他們最初選擇創建三行,但後來決定只需要兩行。所以有意義的是,第三行不會被重新創建。

一開始,我只是用類似我的Page_Load中的以下子程序代碼:

If objCheckbox.Checked = False 
    ' Render the row, and recreate the dynamic controls ' 
Else 
    ' Dont render the row or any of the controls ' 
End If 

但是,似乎發生的是,objCheckbox.Checked總返回,甚至當複選框被打勾時。一旦頁面加載完畢,表格行再次呈現,並且勾號出現在複選框中,所以它不像在回發時丟失值。但在這一點上,我檢查複選框是否打勾,它總是返回,呈現用戶不需要的表格行。

有誰知道如何解決這個問題?我已經閱讀了很多關於.NET ViewState和頁面生命週期的文章,但是我還沒有找到可行的解決方案。我只需要能夠在重新創建一些動態控件之前檢查複選框是否被勾選。

我試過這種替代代碼,它利用ViewState的,但無濟於事:

If objIgnoreCheckbox.ViewState("Checked") = False Then 
    ' Render the row, and recreate the dynamic controls ' 
Else 
    ' Dont render the row or any of the controls ' 
End If 

做這件事時,我得到以下錯誤:

「System.Web.UI.Control 。受保護的可重寫ReadOnly屬性ViewState()由於System.Web.UI.StateBag'受保護',因此無法在此上下文中訪問。

所以我試圖創建一個自定義類,從複選框繼承,並試圖重寫ViewState屬性將其公開,以便它可以被讀取:

Public Class CheckboxControl 

    ' Inherits all Checkbox properties and methods ' 
    Inherits Checkbox 

    ' Create the public ViewState property '   
    Public Overrides ReadOnly Property ViewState As StateBag 

     Get 
      Dim objChecked As Object = ViewState("Checked") 
      If Not (IsNothing(objChecked)) Then 
       Return objChecked 
      End If 
     End Get 

    End Property 

End Class 

但後來我基本上發現你不能用一個公開的覆蓋保護的成員。我創建新班級的經歷很少,所以我很難過。

所以,如果任何人都可以告訴我如何去檢查沉默的複選框,我會永遠感激!我花了整整一個工作日試圖解決問題,但沒有運氣!

在此先感謝!

回答

2

對於靜態控制,控件的視圖狀態被恢復在Page_InitPage_Load之前恰好,所以它們包含在Page_Load的正確值。在Page_Load中創建動態控件,因此它們的視圖狀態爲不正確Page_Load中,並且將在Page_Load之後但在調用事件處理程序之前將其恢復爲MSDN says:

After the Page_Load event has run, but before control event-handling methods are called, the remaining view state information is loaded into the dynamically created controls.

這就是爲什麼Checked返回false,爲什麼改變CheckBox.ViewState知名度不會解決你的問題。

解決方案(未經測試,但我認爲它應該工作):創建所有控制(甚至是那些你不想顯示)在Page_Load。將CheckedChanged的事件處理程序附加到您的CheckBoxes(位於Page_Load)。 Page_Load完成後,ASP.NET將恢復新創建的控件的視圖狀態(這就是爲什麼在Page_Load中創建相同的控件非常重要,以便ASP.NET可以將視圖狀態正確映射到控件), ASP.NET將調用您的事件處理程序來處理已更改的CheckBox。在那裏,你可以刪除你不想顯示的行。


這是你如何添加事件處理

AddHandler objCheckbox.CheckedChanged, AddressOf MyCheckedChangedFunction 

此功能會是這個樣子:

Function MyCheckedChangedFunction(sender As Object, e As EventArgs) 
    Dim objCheckbox = DirectCast(sender, CheckBox) 

    ... access objCheckbox.Changed and do something useful here ... 
End Function 
+0

您好,感謝您的回覆。 我照你的建議做了,並在Page_Load中創建了一個事件處理程序,並將其添加到複選框。我用下面的代碼: objCheckbox.OnCheckedChanged = 「MyFunction的」 但我得到以下錯誤: **'System.Web.UI.WebControls.CheckBox.Protected可重寫子OnCheckedChanged(E作爲System.EventArgs) '在此情況下無法訪問,因爲它是'受保護的'。** 你知道什麼可能會導致此錯誤嗎?正如我之前提到的,當我在無法覆蓋該功能以使其公開之前遇到此錯誤。 謝謝。 – Dom 2009-12-30 09:09:41

+0

我更新了我的答案。要添加一個事件處理程序,你需要訪問'CheckedChanged'(沒有'On')...對不起,如果我的回答在這方面有誤導性。我已經添加了一些示例代碼。 – Heinzi 2009-12-30 09:52:52

+0

嗨,感謝您的意見!雖然當我使用** CheckedChanged **時,我得到以下錯誤**'公共事件CheckedChanged(發件人爲對象,e爲System.EventArgs)'是一個事件,不能直接調用。使用'RaiseEvent'語句來引發一個事件。**但是沒關係,我已經設法排除了這個問題。我在** Page_PreRender **(它工作)期間檢查複選框的狀態,並從該表單中刪除任何行。謝謝你的回覆! – Dom 2009-12-31 11:09:25