none
GridViewで1レコードのうち1つのフィールドを2行目に表示したい RRS feed

  • 質問

  • 開発環境 WindowXp Professional SP2
         VisualStudo2005 Professional

    ASP2.0でデータベース(Oracle9i)と連携したWEBアプリケーション開発を行っています。
    GridViewコントロールをつかってテーブルのデータを以下のように表示したいのですがどのようにすればよいでしょうか。
     ――――――――――――――――――――――――――――
    |1レコード目 |項目1|項目2|項目3|項目4|項目5|項目6|
    |   Button    |――――――――――――――-|    |
    |             | 項目7                            |      |
    |――――――――――――――――――――――――――――|
    |2レコード目 |項目1|項目2|項目3|項目4|項目5|項目6|
    |   Button    |―――――――――――――――-|    |
    |             |項目7                             |      |
    |――――――――――――――――――――――――――――|
    |3レコード目 |項目1|項目2|項目3|項目4|項目5|項目6|
    |   Button    |―――――――――――――――-|    |
    |             | 項目7                            |      |
      ――――――――――――――――――――――――――――
    ご存知の方いらっしゃいましたらよろしくお願いします。
    2006年10月25日 9:09

回答

  • TemplateFieldを使ってこんなことならできます。

    http://dotnetfan.org/blogs/dotnetfanblog/articles/672.aspx

    cellの間の線をどう引くか、という問題はのこりますが。

    2006年10月25日 9:14
  • ちょっと時間が無くて試せませんが、アイディアとしては以下のようになると思います。

    とりあえず、1行に全ての項目を含んでいる普通のGridViewを作成する。RowCreatedかPreRenderイベントで、1行を2行に分割し、必要な形に整形する。イメージとしては1行毎に1行追加して、2段にならないところはRowSpanを2とし、2段目は1段目から移植してきて、その元あった列を削除します。
    以下が参考になると思います。

    GRIDVIEWの同一列内のセルを結合するには
    http://forums.microsoft.com/msdn-ja/ShowPost.aspx?PostID=585776&SiteID=7

    GridViewのHeaderRowについて
    http://forums.microsoft.com/msdn-ja/ShowPost.aspx?PostID=314228&SiteID=7

    気になるのは、GridViewのRowIndexがおかしくなるかもしれませんので、注意が必要です。

    2006年10月25日 10:26
    モデレータ
  • そう言えば昔、ItemTemplate内にHRタグで線を引いて2段にしたことがあります。これはASP.NET 1.1でDataGridで行いました。同じように、Tableタグを使えばできるかもしれません。こちらでできれば、こちらの方がすっきりしますね。所詮GridViewはTableタグに変換されるわけですから、そのセルの中でうまいこと表組みされるようにタグを書いてあげればいいわけです。問題は如何にきれいに見せるかですね。

    #後で時間が取れれば試してみます。

    2006年10月25日 12:41
    モデレータ
  • > とりあえず次は、RowCreatedかPreRenderイベントで、

    やるのならPreRenderイベントがいいんじゃないかな。
    たしかRowCreatedはPostBackでデータがあがった直後とレンダリングの前と2回発生したと思うので、そこでしかできないような処理でなければPreRenderでやったほうがいいと思います。

    2006年10月26日 3:28
  •  るーしぇ さんからの引用
    trapemiya様ありがとうございます。
    さっそく項目1~項目5と項目7をtableタグにいれる方法を試してみました。ほぼイメージ通りにはできたのですが何点か課題が残りました。

    私も試してみたんですが、全然イメージ通りに行きません。Orz
    どうしても、GridViewの中にTableが溶け込みません。如何にもGridViewの中にTableがありますという表示になってしまいます。
    CSSとか得意な人だったらできるかもしれませんね。
    2006年10月26日 5:59
    モデレータ
  • いろいろ調べた結果、RowDataBoundを使うのが一番簡単のようです。
    下の例は、
    +-----+-----+-----+-----+-----+-----+-----+
    |   0   |   1   |   2  |   3   |   4  |   5   |   6  | 
    +-----+-----+-----+-----+-----+-----+-----+

    +-----+-----+-----+-----+-----+-----+
    |        |        |   2  |   3   |   4  |        |  
    +  0  |   1  +-----+-----+-----+  6  +
    |        |        |           5           |        |  
    +-----+-----+-----+-----+-----+-----+
    にしています。

        Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound

            If e.Row.RowType = DataControlRowType.DataRow Then

                Dim table As Table = e.Row.Parent

     

                Dim row As GridViewRow = New GridViewRow(-1, -1, DataControlRowType.DataRow, DataControlRowState.Normal)

                Dim cell As TableCell = New TableCell()

     

                Dim value As String = e.Row.Cells(5).Text

     

                e.Row.Cells.RemoveAt(5)

     

                e.Row.Cells(0).RowSpan = 2

                e.Row.Cells(1).RowSpan = 2

                e.Row.Cells(5).RowSpan = 2

     

                cell.ColumnSpan = 3

                cell.Controls.Add(New LiteralControl(value))

                row.Cells.Add(cell)

                table.Rows.Add(row)

            End If

        End Sub

    2006年10月28日 16:09
    モデレータ
  • > それぞれのCommandAgumentにテーブルの"ID"をバインドさせているので

    このとき、生成されたHTMLを見るとボタンクリック時のIDの情報は含まれていないように思います。
    ボタンの行とボタン名だけをブラウザから返して、サーバ上でIDを取り出しているのではないかと思っているのですが、これが行をプログラムで増やしたりしているとどうもうまく動かないようです。
    解決策は見えていないのですが、一応情報まで。


     

     

    2006年10月30日 4:34
  • ちょっとどこに問題があるのか調べ切れていません。GridViewを継承してRowIndexなんかをいじくってみたりしましたが、ダメでした。もうちょっとGridViewやコントロールが生成される過程について調べる必要があるようです。いくつかのメソッドやプロパティをオーバーライドすればできそうな気もするんですが・・・。あと、ViewStateとの関連なんかも怪しそう。

    2006年10月30日 14:49
    モデレータ
  • そこまでしてGridViewでやる理由がわからないです。
    Repeaterコントロール使うという選択肢はないですか?

    2006年11月15日 0:45
  • ?????????????????????? ???????????????????????????????????????(^^;

      <DefaultProperty("Text"), ToolboxData("<{0}:GridViewEx runat=server></{0}:GridViewEx>")> _

        Public Class GridViewEx

            Inherits System.Web.UI.WebControls.GridView

     

            Protected Overrides Function CreateRow(ByVal rowIndex As Integer, ByVal dataSourceIndex As Integer, ByVal rowType As System.Web.UI.WebControls.DataControlRowType, ByVal rowState As System.Web.UI.WebControls.DataControlRowState) As System.Web.UI.WebControls.GridViewRow

     

                Return New GridViewRowEx(rowIndex, dataSourceIndex, rowType, rowState)

            End Function

     

        End Class

     

        Public Class GridViewRowEx

            Inherits System.Web.UI.WebControls.GridViewRow

     

            Public Sub New(ByVal rowIndex As Integer, ByVal dataItemIndex As Integer, ByVal rowType As DataControlRowType, ByVal rowState As DataControlRowState)

                MyBase.New(rowIndex, dataItemIndex, rowType, rowState)

           End Sub

     

            Protected Overrides Sub RenderContents(ByVal writer As System.Web.UI.HtmlTextWriter)

                If Me.RowType = DataControlRowType.Header Then

                    Me.Cells.RemoveAt(5)

                End If

     

                If Me.RowType = DataControlRowType.DataRow Then

                    Dim value As String = Me.Cells(5).Text

                    Me.Cells.RemoveAt(5)

     

                    Me.Cells(0).RowSpan = 2

                    Me.Cells(1).RowSpan = 2

                    Me.Cells(5).RowSpan = 2

     

                    MyBase.RenderContents(writer)

                    writer.Write("<tr><td colspan=""3"">" + value + "</td></tr>")

                Else

                    MyBase.RenderContents(writer)

                End If

            End Sub

     

        End Class

    2006年11月15日 3:27
    モデレータ
  • ↑いじるとまた崩れるので、上で????になっているところを書いておきます。

    「一応粘って、違う方法を考えてみました。とりあえず、表示だけならうまくいっている感じです。その後の動作の確認はできていません。動作が変なようですと、また考えます。(^^;」

    2006年11月15日 3:33
    モデレータ
  • こちらで実行してみたところ、ページングは表示を含めて正常に行われています。
    るーしぇさんところでは、何かのコードが悪さをしているのかもしれません。
    ちなみにページングは、AllowPaging=trueにしただけです。
    2006年11月17日 1:24
    モデレータ
  • 試してみましたが、こちらでは全てのセルの値を取ることができます。例えば、以下のコードです。

        Protected Sub GridView1_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles GridView1.RowCommand

            System.Diagnostics.Debug.WriteLine(CType(CType(e.CommandSource, Control).NamingContainer, GridViewRow).Cells(5).Text)

        End Sub

    Dim value As String = Me.Cells(5).Text はどこに書かれているんでしょうか?

    2006年11月17日 15:33
    モデレータ
  • う~ん、何でしょう? こちらではちゃんと全てのセルの値が取れます。表示できないは項目12のセルだけなんでしょうか? とりあえず私がうまく言っているaspxを載っけますので、何か違いがないか比べてみて下さい。 

    <%@ Page Language="VB" AutoEventWireup="false" CodeFile="GridView2rows.aspx.vb" Inherits="GridView2rows" %>

    <%@ Register Assembly="WebControlLibraryGridViewEx" Namespace="WebControlLibraryGridViewEx.CustControls"
        TagPrefix
    ="cc1" %>


    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
        
    <title>?3ee?I?y?[?W</title>
    </head>
    <body>
        
    <form id="form1" runat="server">
        
    <div>
            
    <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:testdbConnectionString %>"
                SelectCommand
    ="SELECT [TESTID], [TEST2ID], [TEST1], [TEST2], [TEST3], [TESTADDDATE], [TESTUPDDATE] FROM [TEST]">
            
    </asp:SqlDataSource>
            
    <cc1:GridViewEx ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="TESTID"
                DataSourceID
    ="SqlDataSource1" AllowPaging="True">
                
    <Columns>
                    
    <asp:BoundField DataField="TESTID" HeaderText="TESTID" InsertVisible="False" ReadOnly="True"
                        SortExpression
    ="TESTID" />
                    <
    asp:TemplateField ShowHeader="False">
                        
    <itemtemplate>
    <asp:LinkButton id="LinkButton1" runat="server" Text="??^?g" CausesValidation="false" CommandName="ItemButton" __designer:wfdid="w1"></asp:LinkButton> 
    </itemtemplate>
                    
    </asp:TemplateField>
                    
    <asp:BoundField DataField="TEST1" HeaderText="TEST1" SortExpression="TEST1" />
                    <
    asp:BoundField DataField="TEST2" HeaderText="TEST2" SortExpression="TEST2" />
                    <
    asp:BoundField DataField="TEST3" HeaderText="TEST3" SortExpression="TEST3" />
                    <
    asp:BoundField DataField="TESTADDDATE" HeaderText="TESTADDDATE" SortExpression="TESTADDDATE" />
                    <
    asp:BoundField DataField="TESTUPDDATE" HeaderText="TESTUPDDATE" SortExpression="TESTUPDDATE" />
                </
    Columns>
            
    </cc1:GridViewEx>
            
    <asp:Button ID="Button1" runat="server" Text="Button" /></div>
        
    </form>
    </body>
    </html>

    Colorized by: CarlosAg.CodeColorizer
    2006年11月18日 15:06
    モデレータ
  • 何となくTemplateFieldのような気がしてました。 以下で試してみて下さい。

    Dim value As String = CType(CType(Me.Cells.Item(5), DataControlFieldCell).Controls(1), Label).Text

    2006年11月20日 6:59
    モデレータ

すべての返信

  • TemplateFieldを使ってこんなことならできます。

    http://dotnetfan.org/blogs/dotnetfanblog/articles/672.aspx

    cellの間の線をどう引くか、という問題はのこりますが。

    2006年10月25日 9:14
  • 小野様、迅速な回答ありがとうございます。
    私もいろいろ調べているときにそのページは拝見させていただきやってはみたのですが
    おっしゃるとおりセル間の線引きができなくて断念してしまいました。
    それを解決するにはRepeterコントロールを利用するしかないのでしょうか。

    2006年10月25日 9:41
  • ちょっと時間が無くて試せませんが、アイディアとしては以下のようになると思います。

    とりあえず、1行に全ての項目を含んでいる普通のGridViewを作成する。RowCreatedかPreRenderイベントで、1行を2行に分割し、必要な形に整形する。イメージとしては1行毎に1行追加して、2段にならないところはRowSpanを2とし、2段目は1段目から移植してきて、その元あった列を削除します。
    以下が参考になると思います。

    GRIDVIEWの同一列内のセルを結合するには
    http://forums.microsoft.com/msdn-ja/ShowPost.aspx?PostID=585776&SiteID=7

    GridViewのHeaderRowについて
    http://forums.microsoft.com/msdn-ja/ShowPost.aspx?PostID=314228&SiteID=7

    気になるのは、GridViewのRowIndexがおかしくなるかもしれませんので、注意が必要です。

    2006年10月25日 10:26
    モデレータ
  • そう言えば昔、ItemTemplate内にHRタグで線を引いて2段にしたことがあります。これはASP.NET 1.1でDataGridで行いました。同じように、Tableタグを使えばできるかもしれません。こちらでできれば、こちらの方がすっきりしますね。所詮GridViewはTableタグに変換されるわけですから、そのセルの中でうまいこと表組みされるようにタグを書いてあげればいいわけです。問題は如何にきれいに見せるかですね。

    #後で時間が取れれば試してみます。

    2006年10月25日 12:41
    モデレータ
  • trapemiya様ありがとうございます。
    さっそく
    項目1~項目5と項目7をtableタグにいれる方法を試してみました。ほぼイメージ通りにはできたのですが何点か課題が残りました。
     
    ・1行目の項目1~項目5の文字数がレコードによって異なるためセルの横幅がレコードでばらばらになってしまう。(TDのWidthを明示的に設定するしかないでしょうか。)
    項目6がImageFieldでJpeg画像を表示しているため画像のheightのサイズにGridViwの行のheightが広がってしまいTable(nレコード目)とTable(n+1レコード目)の間に隙間ができてしまう。(画像がWidth固定でHeightは可変なのでTDのHeightを指定するのが難しい状態です。)

    とりあえず次は
    、RowCreatedかPreRenderイベントで、1行を2行に分割する方法を試してみます。
    2006年10月26日 2:16
  • > とりあえず次は、RowCreatedかPreRenderイベントで、

    やるのならPreRenderイベントがいいんじゃないかな。
    たしかRowCreatedはPostBackでデータがあがった直後とレンダリングの前と2回発生したと思うので、そこでしかできないような処理でなければPreRenderでやったほうがいいと思います。

    2006年10月26日 3:28
  •  るーしぇ さんからの引用
    trapemiya様ありがとうございます。
    さっそく項目1~項目5と項目7をtableタグにいれる方法を試してみました。ほぼイメージ通りにはできたのですが何点か課題が残りました。

    私も試してみたんですが、全然イメージ通りに行きません。Orz
    どうしても、GridViewの中にTableが溶け込みません。如何にもGridViewの中にTableがありますという表示になってしまいます。
    CSSとか得意な人だったらできるかもしれませんね。
    2006年10月26日 5:59
    モデレータ
  •  trapemiya さんからの引用

    とりあえず、1行に全ての項目を含んでいる普通のGridViewを作成する。RowCreatedか PreRenderイベントで、1行を2行に分割し、必要な形に整形する。イメージとしては1行毎に1行追加して、2段にならないところはRowSpan を2とし、2段目は1段目から移植してきて、その元あった列を削除します。

    やってみたのですが1行毎に1行追加がうまくいきません。
    RowCreatedイベントで以下のようなソースでやってみると、ヘッダーの次に追加したダミー行がレコードの数だけが連続で挿入され、その下にデータ行が続くといった具合でレコードとレコードの間にうまく挿入されません。
    PreRenderイベントでするのがいいと小野様がおっしゃっていたので先にやってみようとしたのですが、RowIndexの値をEventArgsから取得する方法がわかりませんでした。何か基本的なところで間違えてるのでしょうか・・・。

                Dim row1 As New GridViewRow(-1, -1, DataControlRowType.DataRow, DataControlRowState.Normal)
                Dim cell1 As New TableCell()
                Dim cell2 As New TableCell()
                Dim cell3 As New TableCell()
                Dim cell4 As New TableCell()
                Dim cell5 As New TableCell()
                cell1.Text = " aaa "
                cell2.Text = " bbb"
                cell3.Text =  "ccc"
                cell4.Text = " ddd"
                cell5.Text = " eee"
                row1.Cells.Add(cell1)
                row1.Cells.Add(cell2)
                row1.Cells.Add(cell3)
                row1.Cells.Add(cell4)
                row1.Cells.Add(cell5)
                GridView1.Controls(0).Controls.AddAt(e.Row.RowIndex + 1, row1)

    2006年10月27日 6:45
  • いろいろ調べた結果、RowDataBoundを使うのが一番簡単のようです。
    下の例は、
    +-----+-----+-----+-----+-----+-----+-----+
    |   0   |   1   |   2  |   3   |   4  |   5   |   6  | 
    +-----+-----+-----+-----+-----+-----+-----+

    +-----+-----+-----+-----+-----+-----+
    |        |        |   2  |   3   |   4  |        |  
    +  0  |   1  +-----+-----+-----+  6  +
    |        |        |           5           |        |  
    +-----+-----+-----+-----+-----+-----+
    にしています。

        Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound

            If e.Row.RowType = DataControlRowType.DataRow Then

                Dim table As Table = e.Row.Parent

     

                Dim row As GridViewRow = New GridViewRow(-1, -1, DataControlRowType.DataRow, DataControlRowState.Normal)

                Dim cell As TableCell = New TableCell()

     

                Dim value As String = e.Row.Cells(5).Text

     

                e.Row.Cells.RemoveAt(5)

     

                e.Row.Cells(0).RowSpan = 2

                e.Row.Cells(1).RowSpan = 2

                e.Row.Cells(5).RowSpan = 2

     

                cell.ColumnSpan = 3

                cell.Controls.Add(New LiteralControl(value))

                row.Cells.Add(cell)

                table.Rows.Add(row)

            End If

        End Sub

    2006年10月28日 16:09
    モデレータ
  • trapemiya様、大変解りやすいコードありがとうございます。
    おかげさまでご提示いただいたコードを少し変えるだけで思い通りの機能が実現できました。
    tableタグにいれる方法はやはりおっしゃるとおり行の中にテーブルを挿入している感が完全にはとれないので、行を挿入する方法を試行錯誤しながら模索していたところでした。

    あと問題は、GridViewにテーブル
    (PrimaryKeyは"ID")がすべてのレコード表示されているとき、
      ID>GridViewのレコード数/ 2  の時にButtonをクリックしてもRowCommandイベントが発生せずGridViewのレイアウトが崩れてしまうところです。
    以前をおっしゃられたようにGridViewのRowIDがおかしくなっているのかもしれませんが、今回のケースでは1つのtemplate列にbuttonを2個配置しそれぞれのCommandAgumentにテーブルの"ID"をバインドさせているのであまり関係ないかと思っていたのですが事象の発生条件から見るとやはり関係ありそうです。
    2006年10月30日 2:53
  • > それぞれのCommandAgumentにテーブルの"ID"をバインドさせているので

    このとき、生成されたHTMLを見るとボタンクリック時のIDの情報は含まれていないように思います。
    ボタンの行とボタン名だけをブラウザから返して、サーバ上でIDを取り出しているのではないかと思っているのですが、これが行をプログラムで増やしたりしているとどうもうまく動かないようです。
    解決策は見えていないのですが、一応情報まで。


     

     

    2006年10月30日 4:34
  • ちょっとどこに問題があるのか調べ切れていません。GridViewを継承してRowIndexなんかをいじくってみたりしましたが、ダメでした。もうちょっとGridViewやコントロールが生成される過程について調べる必要があるようです。いくつかのメソッドやプロパティをオーバーライドすればできそうな気もするんですが・・・。あと、ViewStateとの関連なんかも怪しそう。

    2006年10月30日 14:49
    モデレータ
  • あれからいろいろやってみて、RowDataBoundで行っているところを、以下のように若干ソースを変えてRowCreatedで行ってみました。

        Sub GridView1_RowCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowCreated
            If e.Row.RowType = DataControlRowType.DataRow Then
                'Dim table As Table = e.Row.Parent
                Dim GridView As System.Web.UI.WebControls.GridView = sender
                Dim row As GridViewRow = New GridViewRow(-1, -1, DataControlRowType.DataRow, DataControlRowState.Normal)
                row.ID = "Row" + e.Row.RowIndex.ToString
                Dim cell As TableCell = New TableCell()
                Dim value As String = e.Row.Cells(11).Text
                Dim DTtbl As DataTable = GetData()
                value = DTtbl.Rows(e.Row.RowIndex).Item(10).ToString
                e.Row.Cells.RemoveAt(11)
                e.Row.Cells(0).RowSpan = 2
                e.Row.Cells(1).RowSpan = 2
                e.Row.Cells(11).RowSpan = 2
                cell.ColumnSpan = 9
                cell.Controls.Add(New LiteralControl(value))
                row.Cells.Add(cell)
                GridView.Controls(0).Controls.Add(row)
                cell.Text = value
            ElseIf e.Row.RowType = DataControlRowType.Header Then
                e.Row.Cells.RemoveAt(11)
            End If

        End Sub

    理想系↓
     ――――――――――――――――――――――――――――――――――――――――――――――
    |1レコード目|       |項目2|項目3|項目4|項目5|項目6|項目7|項目8|項目9|項目10|       |
    |   Button   | 項目1|―――――――――――――――――――――――――――――――-| 項目11|
    |            |       | 項目12                                                        |       |
     ――――――――――――――――――――――――――――――――――――――――――――――
    |2レコード目|       |項目2|項目3|項目4|項目5|項目6|項目7|項目8|項目9|項目10|       |
    |   Button   | 項目1|―――――――――――――――――――――――――――――――-| 項目11|
    |            |       | 項目12                                                        |       |
     ――――――――――――――――――――――――――――――――――――――――――――――
    |3レコード目|       |項目2|項目3|項目4|項目5|項目6|項目7|項目8|項目9|項目10|       |
    |   Button   | 項目1|―――――――――――――――――――――――――――――――-| 項目11|
    |            |       | 項目12                                                        |       |
     ――――――――――――――――――――――――――――――――――――――――――――――

    としたかったのですが、

     ――――――――――――――――――――――――――――――――――――――――――――――
    |項目12                                                                                      |
    |――――――――――――――――――――――――――――――――――――――――――――――|
    |1レコード目|       |項目2|項目3|項目4|項目5|項目6|項目7|項目8|項目9|項目10|       |
    |   Button   | 項目1|―――――――――――――――――――――――――――――――-| 項目11|
    |            |       | 項目12                                                        |       |
    |――――――――――――――――――――――――――――――――――――――――――――――|
    |2レコード目|       |項目2|項目3|項目4|項目5|項目6|項目7|項目8|項目9|項目10|       |
    |   Button   | 項目1|―――――――――――――――――――――――――――――――-| 項目11|
    |            |       | 項目12                                                        |       |
    |――――――――――――――――――――――――――――――――――――――――――――――|
    |3レコード目|       |   |   |   |   |   |   |   |   |   |     |
    |   Button   | 項目1|項目2|項目3|項目4|項目5|項目6|項目7|項目8|項目9|項目10| 項目11 |
    |            |       |      |      |      |      |      |      |      |      |      |        |
     ――――――――――――――――――――――――――――――――――――――――――――――

    となってしまいます。
    一応ボタンの動きは正常なのですが、行の追加のほうがデータバインドよりも早く実行されるようで惜しいのですがうまくいきませんでした。OTL




    2006年11月9日 8:49
  • そこまでしてGridViewでやる理由がわからないです。
    Repeaterコントロール使うという選択肢はないですか?

    2006年11月15日 0:45
  • まったくそのとおりなんですが、GridViewでこの問題以外の部分は完成したので意地でもGridViewでやりたいという思いがあったのと、なによりRepeaterコントロールを使ったことがないというのが最大の理由でした。
    とりあえずもうちょっとがんばってだめならRepeaterかカスタムコントロールで作成する方法にしようと思います。

    2006年11月15日 1:58
  • ?????????????????????? ???????????????????????????????????????(^^;

      <DefaultProperty("Text"), ToolboxData("<{0}:GridViewEx runat=server></{0}:GridViewEx>")> _

        Public Class GridViewEx

            Inherits System.Web.UI.WebControls.GridView

     

            Protected Overrides Function CreateRow(ByVal rowIndex As Integer, ByVal dataSourceIndex As Integer, ByVal rowType As System.Web.UI.WebControls.DataControlRowType, ByVal rowState As System.Web.UI.WebControls.DataControlRowState) As System.Web.UI.WebControls.GridViewRow

     

                Return New GridViewRowEx(rowIndex, dataSourceIndex, rowType, rowState)

            End Function

     

        End Class

     

        Public Class GridViewRowEx

            Inherits System.Web.UI.WebControls.GridViewRow

     

            Public Sub New(ByVal rowIndex As Integer, ByVal dataItemIndex As Integer, ByVal rowType As DataControlRowType, ByVal rowState As DataControlRowState)

                MyBase.New(rowIndex, dataItemIndex, rowType, rowState)

           End Sub

     

            Protected Overrides Sub RenderContents(ByVal writer As System.Web.UI.HtmlTextWriter)

                If Me.RowType = DataControlRowType.Header Then

                    Me.Cells.RemoveAt(5)

                End If

     

                If Me.RowType = DataControlRowType.DataRow Then

                    Dim value As String = Me.Cells(5).Text

                    Me.Cells.RemoveAt(5)

     

                    Me.Cells(0).RowSpan = 2

                    Me.Cells(1).RowSpan = 2

                    Me.Cells(5).RowSpan = 2

     

                    MyBase.RenderContents(writer)

                    writer.Write("<tr><td colspan=""3"">" + value + "</td></tr>")

                Else

                    MyBase.RenderContents(writer)

                End If

            End Sub

     

        End Class

    2006年11月15日 3:27
    モデレータ
  • ↑いじるとまた崩れるので、上で????になっているところを書いておきます。

    「一応粘って、違う方法を考えてみました。とりあえず、表示だけならうまくいっている感じです。その後の動作の確認はできていません。動作が変なようですと、また考えます。(^^;」

    2006年11月15日 3:33
    モデレータ
  • trapemiya様毎回わかりやすいコードありがとうございます。
    おかげさまでレイアウトが崩れないように実装することができました。
    実は、Repeaterでやりかけてほぼ見た目は実現できたですが、ページングの実装が難しそうなのでGridViewで粘ってました。
    それでGridViewでページングをいざ実装してみると下のようにページの最終レコードの項目12にページ番号が入ってしまって四苦八苦している状況です。
    TemplateFieldにfootertemplateを入れてみても最終レコードの項目11のimagebutton列の下半分が見えなくなるだけでうまくいきません。
    もうちょっとがんばってみます。(^^;


     ――――――――――――――――――――――――――――――――――――――――――――――
    |1レコード目|       |項目2|項目3|項目4|項目5|項目6|項目7|項目8|項目9|項目10|       |
    |   Button   | 項目1|―――――――――――――――――――――――――――――――-| 項目11|
    |            |       | 項目12                                                        |       |
     ――――――――――――――――――――――――――――――――――――――――――――――
    |2レコード目|       |項目2|項目3|項目4|項目5|項目6|項目7|項目8|項目9|項目10|       |
    |   Button   | 項目1|―――――――――――――――――――――――――――――――-| 項目11|
    |            |       | 項目12                                                        |       |
     ――――――――――――――――――――――――――――――――――――――――――――――
    |3レコード目|       |項目2|項目3|項目4|項目5|項目6|項目7|項目8|項目9|項目10|       |
    |   Button   | 項目1|―――――――――――――――――――――――――――――――-| 項目11|
    |            |       | ここにページ番号が入る                                        |       |
     ――――――――――――――――――――――――――――――――――――――――――――――


    2006年11月16日 23:51
  • こちらで実行してみたところ、ページングは表示を含めて正常に行われています。
    るーしぇさんところでは、何かのコードが悪さをしているのかもしれません。
    ちなみにページングは、AllowPaging=trueにしただけです。
    2006年11月17日 1:24
    モデレータ
  • 申し訳ありません、ページング表示の件は私の間違いでした。(そもそもカスタムコントロールを利用できていなかったです)

    それでページング表示もうまくいくようになったのですが
       Dim value As String = Me.Cells(5).Text
    のところでうまくセルの値が取得できず、項目12の部分がNullになってしまいます。
    デバッグしてみたのですが、
     
    Me.Cells(1).Textの値にはIDの値が入っているのですが、そのほかのセルはすべて値が入っていないようです。

    何か根本的に間違っていたらすみません。(^^;

    2006年11月17日 9:33
  • 試してみましたが、こちらでは全てのセルの値を取ることができます。例えば、以下のコードです。

        Protected Sub GridView1_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles GridView1.RowCommand

            System.Diagnostics.Debug.WriteLine(CType(CType(e.CommandSource, Control).NamingContainer, GridViewRow).Cells(5).Text)

        End Sub

    Dim value As String = Me.Cells(5).Text はどこに書かれているんでしょうか?

    2006年11月17日 15:33
    モデレータ
  •  trapemiya さんからの引用

    Dim value As String = Me.Cells(5).Text はどこに書かれているんでしょうか?

    すみませんお世話かけます。

    trapemiyaさんが書いてくださったコードの

          Protected Overrides Sub RenderContents(ByVal writer As System.Web.UI.HtmlTextWriter)

                If Me.RowType = DataControlRowType.Header Then

                    Me.Cells.RemoveAt(5)

                End If

     

                If Me.RowType = DataControlRowType.DataRow Then

                    Dim value As String = Me.Cells(5).Text ← ここの部分です

                    Me.Cells.RemoveAt(5)

     

                    Me.Cells(0).RowSpan = 2

                    Me.Cells(1).RowSpan = 2

                    Me.Cells(5).RowSpan = 2

     

                    MyBase.RenderContents(writer)

                    writer.Write("<tr><td colspan=""3"">" + value + "</td></tr>")

                Else

                    MyBase.RenderContents(writer)

                End If

            End Sub

     

     

    2006年11月18日 11:11
  • う~ん、何でしょう? こちらではちゃんと全てのセルの値が取れます。表示できないは項目12のセルだけなんでしょうか? とりあえず私がうまく言っているaspxを載っけますので、何か違いがないか比べてみて下さい。 

    <%@ Page Language="VB" AutoEventWireup="false" CodeFile="GridView2rows.aspx.vb" Inherits="GridView2rows" %>

    <%@ Register Assembly="WebControlLibraryGridViewEx" Namespace="WebControlLibraryGridViewEx.CustControls"
        TagPrefix
    ="cc1" %>


    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
        
    <title>?3ee?I?y?[?W</title>
    </head>
    <body>
        
    <form id="form1" runat="server">
        
    <div>
            
    <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:testdbConnectionString %>"
                SelectCommand
    ="SELECT [TESTID], [TEST2ID], [TEST1], [TEST2], [TEST3], [TESTADDDATE], [TESTUPDDATE] FROM [TEST]">
            
    </asp:SqlDataSource>
            
    <cc1:GridViewEx ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="TESTID"
                DataSourceID
    ="SqlDataSource1" AllowPaging="True">
                
    <Columns>
                    
    <asp:BoundField DataField="TESTID" HeaderText="TESTID" InsertVisible="False" ReadOnly="True"
                        SortExpression
    ="TESTID" />
                    <
    asp:TemplateField ShowHeader="False">
                        
    <itemtemplate>
    <asp:LinkButton id="LinkButton1" runat="server" Text="??^?g" CausesValidation="false" CommandName="ItemButton" __designer:wfdid="w1"></asp:LinkButton> 
    </itemtemplate>
                    
    </asp:TemplateField>
                    
    <asp:BoundField DataField="TEST1" HeaderText="TEST1" SortExpression="TEST1" />
                    <
    asp:BoundField DataField="TEST2" HeaderText="TEST2" SortExpression="TEST2" />
                    <
    asp:BoundField DataField="TEST3" HeaderText="TEST3" SortExpression="TEST3" />
                    <
    asp:BoundField DataField="TESTADDDATE" HeaderText="TESTADDDATE" SortExpression="TESTADDDATE" />
                    <
    asp:BoundField DataField="TESTUPDDATE" HeaderText="TESTUPDDATE" SortExpression="TESTUPDDATE" />
                </
    Columns>
            
    </cc1:GridViewEx>
            
    <asp:Button ID="Button1" runat="server" Text="Button" /></div>
        
    </form>
    </body>
    </html>

    Colorized by: CarlosAg.CodeColorizer
    2006年11月18日 15:06
    モデレータ
  • すみません、何度もお世話かけます。
    比較したところ私のほうは主に列にBoundFiledではなくTemplateFieldを使っているせいで値が取れてないみたいでした。(値をとろうとしている列はBoundFiledなのですが
     Dim value As String =  Ctype(Me.Findcontrol("label1"), Label).Text
    そこで、上のコードlで値が取れないかやってみたのですが、「オブジェクト参照がオブジェクトインスタンスに設定されていません。」のエラーが返ってきて取れないようです。
    下が現在のソースです、もうちといろいろやってみます(^^;)

         <cc1:GridViewEx ID="GridView1"  runat="server" CellPadding="3" AutoGenerateColumns="False"
                OnRowCommand="GridView1_RowCommand" BackColor="White" BorderColor="#CCCCCC"
                BorderWidth="1px" BorderStyle="None" DataKeyNames="ID" Font-Names="Arial" AllowPaging="true">
                <FooterStyle BackColor="red"  ForeColor="#000066" />
                <SelectedRowStyle BackColor="#669999" ForeColor="White" Font-Bold="True" />
                <HeaderStyle BackColor="#006699" Font-Bold="True" ForeColor="White"  />
           <Columns>
            <asp:TemplateField>
               <ItemTemplate>
                <asp:Button ID="Button1"  runat="server" CausesValidation="false" CommandName="Select"
                                    Text="編集" CommandArgument='<%#DataBinder.Eval(Container.DataItem, "ID")%>' />
                </ItemTemplate>               
            </asp:TemplateField>
            <asp:BoundField HeaderText="項目1" DataField="項目1" InsertVisible="false" ReadOnly="true" />
            <asp:TemplateField HeaderText="項目2">
               <ItemTemplate>
                   <div align="CENTER" nowrap="nowrap">  
                   <%#DataBinder.Eval(Container.DataItem, "項目2")%>
                    </div>
               </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="項目3">
               <ItemTemplate>
                   <div align="CENTER" nowrap="nowrap">  
                   <%#DataBinder.Eval(Container.DataItem, "項目3-1")%>
                   <br />
                   <%#DataBinder.Eval(Container.DataItem, "項目3-2")%>
                   </div>
               </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="項目4">
               <ItemTemplate>
                   <div align="CENTER">  
                   <%#DataBinder.Eval(Container.DataItem, "項目4-1")%>
                   <br />
                   <%#DataBinder.Eval(Container.DataItem, "項目4-2")%>
                   </div>
               </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="項目5">
               <ItemTemplate>
               <div align="right">
                    <%#DataBinder.Eval(Container.DataItem, "項目5-1")%><br />
                    <%#DataBinder.Eval(Container.DataItem, "項目5-2")%>
               </div>
               </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="項目6">
               <ItemTemplate>
               <div align="right">
                    <%#DataBinder.Eval(Container.DataItem, "項目6-1")%>
                    <br />
                    <%#DataBinder.Eval(Container.DataItem, "項目6-2")%>
                    </div>
               </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="項目7">
                <ItemTemplate>
                    <%#DataBinder.Eval(Container.DataItem, "項目7")%>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="項目8">
                <ItemTemplate>
                    <div align="right">
                    <%#DataBinder.Eval(Container.DataItem, "項目8-1")%><br />
                    <%#DataBinder.Eval(Container.DataItem, "項目8-2")%>
                   </div>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="項目9">
                <ItemTemplate>
                    <%#DataBinder.Eval(Container.DataItem, "項目9")%>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="項目10">
                <ItemTemplate >
                    <%#DataBinder.Eval(Container.DataItem, "項目10")%>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="項目12">
                <ItemTemplate>
                    <asp:label ID="Label1"><%#DataBinder.Eval(Container.DataItem, "項目12")%></asp:label>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField>
                 <ItemTemplate>
                    <asp:Imagebutton ID="Image1" runat="server" CommandName="Image"
                    CommandArgument='<%# Eval("ID") %>'
                    Width="96" Height="72" ImageUrl='<%# Eval("ID", "OutputDBImage.aspx?id={0}") %>'  />                               
                 </ItemTemplate>
            </asp:TemplateField>
           </Columns>
           <RowStyle ForeColor="#000066" />
           <PagerStyle  BackColor="White" ForeColor="#000066" HorizontalAlign="Left" />           
        </cc1:GridViewEx>

    2006年11月20日 2:20
  • 何となくTemplateFieldのような気がしてました。 以下で試してみて下さい。

    Dim value As String = CType(CType(Me.Cells.Item(5), DataControlFieldCell).Controls(1), Label).Text

    2006年11月20日 6:59
    モデレータ
  • trapemiya様、いつもありがとうございます。
    おかげさまで完璧に思い通りの機能を実現することができました。
    長い間お世話かけまして申し訳ございませんでした。
    これからはここで回答させていただけるぐらいのレベルになるようにがんばります。
    2006年11月20日 10:07