トップ回答者
GridViewの入れ子のデータ取得とヘッダー行の追加について

質問
-
GridViewの入れ子のデータ取得とヘッダー行の追加について教えて下さい。
・GridViewの入れ子のデータ取得
以下のようにGridViewの中にGridViewを入れ子にしています。
内側のGV2のRowDataBoundイベント時にHF1のデータを取得したいと思っていますが、
オブジェクトの参照ができないようでエラーになります。どのように記述すれば
データを取得できるのでしょうか?(プログラムは、一部省略しています)<asp:GridView ID="GV1" runat="server">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:HiddenField ID="HF1" runat="server" Value='<%# Eval("C_Date") %>' />
<asp:GridView ID="GV2" runat="server" AutoGenerateColumns="False" DataSourceID="ODS2" OnRowDataBound="GV2_RowDataBound">
<Columns>
<asp:BoundField DataField="User" HeaderText="名前" />
<asp:BoundField DataField="Col_1" HeaderText="1" />
<asp:BoundField DataField="Col_2" HeaderText="2" />
<asp:BoundField DataField="Col_3" HeaderText="3" />
<asp:BoundField DataField="Col_4" HeaderText="4" />
</Columns>
</asp:GridView>
<asp:ObjectDataSource ID="ODS2" runat="server">
<SelectParameters>
<asp:ControlParameter ControlID="HF1" />
</SelectParameters>
</asp:ObjectDataSource>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>・ヘッダー行の追加
ヘッダーが「名前 1 2 3 4」となりますが、このヘッダーの2行目に
行を追加して2行にしたいと思っています。どのように記述すれば追加できるのでしょうか?
「名前 1 2 3 4」
「 月 火 水 木」以下のようにすれば、元のヘッダーの上に追加することはできましたが、下の行に
追加しようとAddAt(1, row1)に変更すればエラーになってしまいます。
Protected Sub GV2_RowCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs)
Dim row1 As New GridViewRow(-1, -1, DataControlRowType.Header, DataControlRowState.Normal)
'挿入したい行を追加処理 月 火 水 木
sender.Controls(0).Controls.AddAt(0, row1)
End Subすみませんが、ご指導よろしくお願いします。
回答
-
> 「指定された引数は、有効な値の範囲内にありません。
> パラメーター名: index」です。それは CType(sender, GridView).Controls(0).Controls に Control が
ない状態で、インデックス 1 の位置に Control を追加しようとしたから
でしょう。RowCreated ではなくて RowDataBound イベントのハンドラで行えばうま
くいくと思います。ただし、それでうまくいっても、ポストバックで表示が崩れるかもしれま
せん。その場合は、GridView の EnableViewState を False にしてみて
ください。(そのような問題があるから ListView の使用をお勧めしたの
ですが)
> ODS2 の Selecting イベントで取得できましたが、なぜ以下のような記
> 述で無理なのでしょうか?Selecting イベントと RowDataBound イベントはどちらが早く発生するか、
パラメータはどのタイミングで渡す必要があるかを考えましょう。- 回答としてマーク プログラム初心者です 2011年4月20日 10:33
すべての返信
-
返信ありがとうございます。
ヘッダーだけ2行にします。イメージは以下のようにカレンダーにユーザーの状況を表示したいと思っています。
1 2 3 4 5 ・・・
月 火 水 木 金
A男 ○ ○
B子 ○ ×
>ヘッダーだけ 2 行にしたいなら何とかなると思います。エラーが
>出るのは sender をキャストしてないからではないですか?質問時のエラーに間違いがありました。
「指定された引数は、有効な値の範囲内にありません。
パラメーター名: index」です。CType(sender, GridView).Controls(0).Controls.AddAt(0, row1) では、ヘッダーの上に追加
曜日は、日付の下に表示したいため
CType(sender, GridView).Controls(0).Controls.AddAt(1, row1) で、エラーになります。>ODS2 の Selecting イベントでデータを渡すことができると思い
>ます。
ODS2 の Selecting イベントで取得できましたが、なぜ以下のような記述で無理なのでしょうか?
Protected Sub GV2_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs)
If e.Row.RowType = DataControlRowType.DataRow Then
Dim DateGet As Date = CDate(CType(GV1.FindControl("HF1"), HiddenField).Value)End If
End Subよろしくお願いします。
-
> 「指定された引数は、有効な値の範囲内にありません。
> パラメーター名: index」です。それは CType(sender, GridView).Controls(0).Controls に Control が
ない状態で、インデックス 1 の位置に Control を追加しようとしたから
でしょう。RowCreated ではなくて RowDataBound イベントのハンドラで行えばうま
くいくと思います。ただし、それでうまくいっても、ポストバックで表示が崩れるかもしれま
せん。その場合は、GridView の EnableViewState を False にしてみて
ください。(そのような問題があるから ListView の使用をお勧めしたの
ですが)
> ODS2 の Selecting イベントで取得できましたが、なぜ以下のような記
> 述で無理なのでしょうか?Selecting イベントと RowDataBound イベントはどちらが早く発生するか、
パラメータはどのタイミングで渡す必要があるかを考えましょう。- 回答としてマーク プログラム初心者です 2011年4月20日 10:33
-
>RowCreated ではなくて RowDataBound イベントのハンドラで行えばうま
>くいくと思います。変更したところ表示できるようになりました。ありがとうございます。
>Selecting イベントと RowDataBound イベントはどちらが早く発生するか、
>パラメータはどのタイミングで渡す必要があるかを考えましょう。
Selecting イベントのほうが早く発生します。パラメータは,Selecting イベント時だと思います。
GV2_RowDataBoundイベント時には、パラメータも渡し終わり、HF1にもデータが渡っているように
思っています。HF1にもデータが渡っているからこそ、GV2_RowDataBoundイベントで表が生成されていると思っています。
すみませんが、間違っている点をもう少し教えていただけませんでしょうか? -
>よく分かりませんが、目的の表が生成されたんですか?
お陰様で目的の表が生成できました。ありがとうございます。
ただ、なぜ
Protected Sub GV2_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs)
If e.Row.RowType = DataControlRowType.DataRow Then
Dim DateGet As Date = CDate(CType(GV1.FindControl("HF1"), HiddenField).Value)End If
End Subの記述で駄目なのか知りたいと思っています。
-
> ただ、なぜ
>
> Protected Sub GV2_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs)
> If e.Row.RowType = DataControlRowType.DataRow Then
> Dim DateGet As Date = CDate(CType(GV1.FindControl("HF1"), HiddenField).Value)
> End If
> End Sub
>
> の記述で駄目なのか知りたいと思っています。先に「GV2_RowDataBoundイベントで表が生成されている」と書いて
あったので、上記のコードでうまくいったと思ったいましたが、違
うようですね。断片的なコードからでははっきり分かりませんが・・・
抽出の条件に使うパラメータ (C_Date ですか?) は HF1 を介して
ObjectDataSource.SelectMethod に設定したメソッドに渡し、それ
から DB にクエリを投げてデータを取得しようとしているのですよ
ね。クエリを投げるとき(Selecting イベント)にパラメータが必要な
のに、それより後のタイミング(RowDataBound イベント)で HF1
からパラメータを取得しても手遅れではないのですか? -
SurferOnWww様。
いつもご回答ありがとうございます。
>抽出の条件に使うパラメータ (C_Date ですか?) は HF1 を介して
>ObjectDataSource.SelectMethod に設定したメソッドに渡し、それ
>から DB にクエリを投げてデータを取得しようとしているのですよ
>ね。そうです。
>クエリを投げるとき(Selecting イベント)にパラメータが必要な
>のに、それより後のタイミング(RowDataBound イベント)で HF1
>からパラメータを取得しても手遅れではないのですか?当初、以下のプログラムで HF1の年月を取得し、月によって替わる最終日(28~31日)の列を表示、非表示に変更しようとし、なぜ取得
できないのか疑問に思ったためです。ただ、お陰様で、Selecting イベントで取得でき、目的の表が表示されています。
Protected Sub GV2_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs)
If e.Row.RowType = DataControlRowType.DataRow Then
Dim DateGet As Date = CDate(CType(GV1.FindControl("HF1"), HiddenField).Value)End If
End Sub