3

長々とした投稿で申し訳ありませんが、作成中の .NET ページで問題が発生しています。

最後の質問: Page_Load サブルーチン中に動的に作成されたチェックボックスの「Checked」プロパティを確認するにはどうすればよいですか?

詳細:基本的に、ユーザーが選択した数に基づいていくつかのテーブル行を動的に作成する VB.NET ページがあります。たとえば、ユーザーがドロップダウン リストから「3」を選択すると、ページはポスト バックし、3 つのテーブル行を作成します。各行には、いくつかのテキスト ボックス、ドロップダウン リスト、およびチェックボックスが含まれています (これらはすべて、単純な HTML コントロールではなく、.NET フォーム コントロールです)。

通常、ユーザーはフォーム コントロールにいくつかの詳細を入力し、[送信] ボタンをクリックします。その後、ページは各行を繰り返し処理し、データを SQL Server テーブルに挿入します。

ただし、ユーザーがその行のチェックボックスをオンにすると、ページはその行を無視し、ユーザーが [送信] をクリックしたときにその行のデータをデータベースに挿入しないことを意味します。

これはうまく機能しますが、問題があります。ユーザーが [送信] をクリックし、フォーム コントロールに入力された値の一部が無効な場合 (たとえば、ユーザーが名前を入力しなかった場合)、ページはデータを送信せず、代わりにエラーを表示します。変更する必要がある値をユーザーに通知します。ただし、たとえば、ユーザーが 3 つの行を作成し、(チェックボックスをオンにして) 3 行目を「無視」することを決定した場合、ページがポストバックされたときに無効なエントリが見つかり、ユーザーにフォームを再表示してそれらを許可します。エラーを修正するには、ページが 3 行目を完全にレンダリングしないようにしたいと思います。結局、最初は 3 つの行を作成することを選択しましたが、必要なのは 2 つだけであると判断しました。したがって、3 行目が再作成されないのは理にかなっています。

まず、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は常にFalseを返しているように見えました。ページが読み込まれると、テーブルの行が再びレンダリングされ、チェックボックスにチェックマークが表示されたので、ポストバックで値が失われたわけではありません。しかし、チェックボックスがオンになっているかどうかを確認した時点で、常にFalseが返され、ユーザーが必要としないテーブル行がレンダリングされます。

この問題を回避する方法を知っている人はいますか? 私は .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.Protected Overridable ReadOnly Property ViewState() As System.Web.UI.StateBag」は「保護」されているため、このコンテキストではアクセスできません。

そこで、Checkbox から継承したカスタム クラスを作成しようとし、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

しかし、基本的に、保護されたメンバーをパブリックメンバーでオーバーライドできないことがわかりました。新しいクラスなどを作成した経験がほとんどないので、困惑しています。

だから、誰かがチェックボックスをチェックする方法を教えてくれたら、私は永遠に感謝します! 問題の解決に 1 日を費やしましたが、うまくいきませんでした。

前もって感謝します!

4

1 に答える 1

2

静的コントロールの場合、コントロールの表示状態はで復元されます。これは、のPage_Init前に発生するため、で正しい値がPage_Load含まれています。動的コントロールはで作成されるため、ビューステートはで正しくなく、イベントハンドラーを呼び出す前に復元されます。MSDNによると:Page_LoadPage_LoadPage_Load Page_Load

Page_Loadイベントが実行された後、コントロールイベント処理メソッドが呼び出される前に、残りのビューステート情報が動的に作成されたコントロールにロードされます。

これがCheckedfalseを返す理由であり、の可視性を変更してもCheckBox.ViewState問題が解決しない理由です。

解決策(テストされていませんが、機能するはずです):ですべてのコントロール(表示したくないものも含む)を作成しますPage_LoadCheckedChanged(内の)チェックボックスにイベントハンドラーをアタッチしますPage_Load。終了後Page_Load、ASP.NETは、新しく作成されたコントロールのビューステート(ASP.NETがビューステートをコントロールに正しくマップできるように、Page_Loadで同じコントロールを作成することが重要である理由)とASPを復元します。 NETは、変更されたチェックボックスに対してイベントハンドラーを呼び出します。そこで、表示したくない行を削除できます。


これは、イベントハンドラーを追加する方法です

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
于 2009-12-29T16:55:20.137 に答える