none
GridViewのセルをクリックしたときのイベントを捕捉したい。 RRS feed

  • 質問

  • いつもお世話になっております。
    ASP&VB.NETでWebアプリの開発をしています。

    タイトルにあるとおりGridViewのセルをクリックしたときのイベントを捕捉したいと考えています。
    各カラムは<A href ~ /A>で別画面で特定のファイルを表示、保存できるようにしています。
    GridView内のセルがクリックされたときのイベントを捕捉する手段はありますでしょうか?

    現在は以下のような定義となっています。

    <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" 
        Font-Bold="True" ShowHeader="False" 
        BorderColor="Black">
        <Columns>
            <asp:BoundField HeaderText="A" HtmlEncode="false" DataField="Ext" >
                <ItemStyle BorderColor="Black" Wrap="False" HorizontalAlign="Center" Width="60px"/>
            </asp:BoundField>
            <asp:BoundField HeaderText="B" HtmlEncode="false" DataField="FileName" >
                <ItemStyle BorderColor="Black" Wrap="False" HorizontalAlign="Center" Width="700px"/>
            </asp:BoundField>
            <asp:BoundField HeaderText="C" HtmlEncode="false" DataField="FD">
                <ItemStyle BorderColor="Black" Wrap="False" HorizontalAlign="Center" Width="60px"/>
            </asp:BoundField>
            <asp:BoundField HeaderText="D" DataField="UploadCount">
                <ItemStyle BorderColor="Black" Wrap="False" HorizontalAlign="Center" Width="50px"/>
            </asp:BoundField>
            <asp:BoundField HeaderText="E" DataField="DownladCount" >
                <ItemStyle BorderColor="Black" Wrap="False" HorizontalAlign="Center" Width="50px"/>
            </asp:BoundField>
            <asp:BoundField HeaderText="F" DataField="Date" >
                <ItemStyle BorderColor="Black" Wrap="False" HorizontalAlign="Center" Width="200px"/>
            </asp:BoundField>
        </Columns>
    </asp:GridView>
    






    TemplateField内にLinkButtonを配置してCommandNameを設定しRowCommandイベントで捕捉出来ないか試行しましたが上手くいきませんでした。
    参考サイトやみなさまからのアドバイスなどいただけたらと思います。
    よろしくお願い致します。
    2009年5月12日 4:05

回答

  • 追加したLinkButtonにOnClickイベント追加してみてはいかがでしょうか?
    <asp:LinkButton ID="LinkButton1" runat="server" CommandName="FileNameClick" OnClick="LinkButton1_Click">

    コード
    Protected Sub LinkButton1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles LinkButton1.Click
       '処理
    End Sub

    これで要件は満たすでしょうか?

    VBは詳しくありませんので、コード記述に不備があるかもしれません。。


    MCITP(Database Developer/Database Administrator) MCTS(SQL Server 2005/Web Applications)
    • 回答としてマーク sk7474 2009年5月22日 9:06
    2009年5月12日 6:12
  • OnClickイベントでも良いんですが、たぶん、どの行のボタンがクリックされたかが知りたいのではないかと思います。
    その場合は、GridViewのRowCreatedイベントとRowCommandイベントを使用して下さい。

    Protected 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 linkBtn As LinkButton
    
          linkBtn = CType(e.Row.FindControl("LinkButton1"), LinkButton)
          linkBtn.CommandArgument = Clickされた時に渡したいもの
        End If
    
    End Sub
    
    
    Protected Sub GridView1_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles GridView1.RowCommand
    
       Select Case e.CommandName
          Case "FileNameClick"
             何かの処理。RowCreatedイベントでセットした値はe.CommandArgumentで
             手に入る。
          Case Else
       End Select
    
    End Sub



    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    • 回答としてマーク sk7474 2009年5月22日 9:06
    2009年5月12日 6:55
    モデレータ
  • 以下のようなコードで実行した結果、LinkButtonクリック時にRowCommandイベントに到達することができませんでした。


    <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" 
    
        Font-Bold="True" ShowHeader="False" 
    
        BorderColor="Black">
    もしかして、<asp:GridView> タグ内に以下記述が不足しているので到達しないと言う事でしょうか??
     OnRowCommand="GridView1_RowCommand"

    MCITP(Database Developer/Database Administrator) MCTS(SQL Server 2005/Web Applications)
    • 回答としてマーク sk7474 2009年5月22日 9:06
    2009年5月12日 7:18
  • FileNameをバインドしているLinkButtonをクリックした場合に、RowCommandイベントが発生するものと考えていますが認識に間違いはありませんでしょうか?
    間違いありません。私も勘違いしておりましたが、結局、RowCommandイベントが発生しないというのが問題のようですね。RowCommandイベントに到達しないというのは、そこにブレークポイントをセットしても止まらないということなのでしょうか? 例えば、
    System.Diagnostics.Debug.WriteLine("LinkButton Click! " & e.CommandArgument)
    の一行をRowCommandイベントハンドラに追加してデバッグ実行しても、出力ウインドウに表示されないのでしょうか?
    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    • 回答としてマーク sk7474 2009年5月22日 9:05
    2009年5月12日 7:49
    モデレータ
  • またしてもRowCommandイベントに到達することができませんでした。
    そのほかになにかお気づきの点がありましたらご教授のほどよろしくお願い致します。

    クローバー様

    VBに詳しくないので、勉強がてらサンプルを作成してみましたが、正常にイベントに到達しました。
    サンプルは以下です。
    開発環境:VS2005 VB Webアプリケーション

    -------------- aspx ここから  --------------
    <%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Default.aspx.vb" Inherits="Sample._Default" %>

    <!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>無題のページ</title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" Font-Bold="True" ShowHeader="False"
            BorderColor="Black" OnRowCommand = "GridView1_RowCommand">
                <Columns>
                    <asp:TemplateField>
                        <ItemTemplate>
                            <asp:LinkButton ID="LinkButton1" runat="server" CommandName="FileNameClick">
                            <%#DataBinder.Eval(Container.DataItem, "FileName")%></asp:LinkButton>
                        </ItemTemplate>
                    </asp:TemplateField>
               </Columns>
            </asp:GridView>
        </div>
        </form>
    </body>
    </html>
    -------------- aspx ここまで  --------------

    -------------- aspx.vb ここから  -------------
    Partial Public Class _Default
        Inherits System.Web.UI.Page

        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            If Not IsPostBack Then
                Dim dt As DataTable
                Dim dr As DataRow
                dt = New DataTable()
                dt.Columns.Add("FileName", System.Type.GetType("System.String"))
                dr = dt.NewRow()
                dr("FileName") = "FileName:1"
                dt.Rows.Add(dr)

                GridView1.DataSource = dt
                GridView1.DataBind()
            End If
        End Sub

        Protected Sub GridView1_RowCommand(ByVal sender As System.Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles GridView1.RowCommand
            Response.Redirect("http://msdn.microsoft.com/ja-jp/default.aspx")
        End Sub
    End Class
    -------------- aspx.vb ここまで  -------------

    何か参考になれば幸いです。


    MCITP(Database Developer/Database Administrator) MCTS(SQL Server 2005/Web Applications)
    • 回答としてマーク sk7474 2009年5月22日 9:05
    2009年5月12日 11:13
  • > 各カラムは<A href ~ /A>で別画面で特定のファイルを表示、保存できるようにしています。

    とのことですが、それで何故、

    > TemplateField内にLinkButtonを配置してCommandNameを設定しRowCommandイベントで捕捉出来
    > ないか試行しましたが上手くいきませんでした。

    という話になるのでしょうか?

    LinkButton は外観が違うだけで Button と同じで、ハイパーリンク(<A href ~ /A>)の役目
    は果たせないと思いますが。

    各カラム、セルの中身はハイパーリンク(<A href ~ /A>)のままにしておいて、それがクリック
    されたとき href で指定したページに飛ぶのと同時に、どのカラム/セルがクリックされたかサーバー
    側で取得したいということですか?

    そうであれば、GridView の各 Cell の OnClick 属性に JavaScript の function を設定して
    input type="hidden" の value 属性に必要な情報を設定し、form を submit してやるという方
    法が考えられます。

    見当違いでしたら失礼しました。

    • 回答としてマーク sk7474 2009年5月22日 9:05
    2009年5月12日 14:41
  • 大外しだったらごめんなさい。

    RowCommand イベントには到達していないとして、その時にポストバックは発生しているのでしょうか?(Load イベントを通過しているかとか)
    ちゃんと LinkButton で生成されたリンクをクリックしているのですよねぇ。各セルの <A href ~ /A> ではなく。
    • 回答としてマーク sk7474 2009年5月22日 9:04
    2009年5月13日 1:22
  • なるほど。そういうことでしたか。とりあえず、RowCommandイベントハンドラに以下のように書いてみて下さい。

    ClientScript.RegisterStartupScript(Me.GetType(), _
                      "hogeKey", _
                      "<script type='text/javascript'>window.open('Hoge.aspx'," & _
                      "'hogeName'," & _
                      "'width=300,height=300')</script>")

    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    • 回答としてマーク sk7474 2009年5月22日 9:04
    2009年5月13日 4:52
    モデレータ
  • > 今まではDataTableに<A href ~ /A>を設定してGridViewにバインドしてファイルの表示、保存をしていましたが
    > ファイルの表示、保存時に何度そのファイルが表示されたかなどのカウントを行う必要が出てきたため
    > RowCommandイベントでそのほか(ファイルの表示、保存)の処理を行おうと考えました。

    色々方法はありますが、とりあえず以下の方法をご紹介します。(1) は先のレスで紹介した方法です。

    (1) クローバーさんが最初に行ったように A タグを使用。その A タグを格納する GridView の各 Cell の
      OnClick 属性に JavaScript を設定して input type="hidden" の value 属性にどのファイルが選択さ
      れたか等の必要な情報を設定し、form を submit してやる方法。

    (2) LinkButton を使用。LinkButton の Text には A タグでなくファイル名の文字列のみを設定。ファイル
      を開くためには OnClientClick プロパティに JavaScript(window.open) を設定。同時に RowCommand
      イベントでどのファイルが選択されたか等の情報を取得。

    ご参考までに、検証に使ったコードもアップしておきます。

    <%@ Page Language="C#" %>
    <%@ Import Namespace="System.Data" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <script runat="server">
        protected DataTable CreateDataTable()
        {
            DataTable dt = new DataTable();
            DataRow dr;
    
            dt.Columns.Add(new DataColumn("Id", typeof(int)));
            dt.Columns.Add(new DataColumn("A-Tag", typeof(string)));
            dt.Columns.Add(new DataColumn("Filename", typeof(string)));
    
            for (int i = 0; i < 10; i++)
            {
                dr = dt.NewRow();
                dr["Id"] = i;
                dr["A-Tag"] = "<a href=\"../Data/Excel.xls\" target='_blank'>Excel.xls</a>";
                dr["Filename"] = "Excel.xls";
                dt.Rows.Add(dr);
            }
            return dt;
        }
    
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                GridView1.DataSource = CreateDataTable();
                GridView1.DataBind();
            }
            else
            {
                // 方法1: 
                // A タグを使用。その cell の onclick 属性に JavaScript を設定。JavaScript で HiddenField の
                // Value 属性にどのファイルが選択されたか等の必要な情報をセットし、form を submit して取得。
                Label1.Text = HiddenField1.Value;
                Label2.Text = String.Empty;
            }
        }
    
        protected string JavaScriptString1(string filename)
        {
            return String.Format("window.open('../Data/{0}', '_blank')", filename);
    
        }
    
        protected string JavaScriptString2(string filename)
        {
            return String.Format("javascript:PostBack({0});", filename);
        }
            
        protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
        {
            // 方法2: 
            // LinkButton を使用し、OnClientClick プロパティに window.open を設定して選んだファイルを開く。
            // 同時に RowCommand イベントでどのファイルが選択されたか等の情報を取得
            Label1.Text = String.Empty;
            Label2.Text = String.Format("Id: {0}, Filename: {1}", e.CommandName, e.CommandArgument.ToString());
        }
    
        protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                string filename = ((LinkButton)e.Row.Cells[2].FindControl("LinkButton1")).Text;
                e.Row.Cells[1].Attributes["onclick"] = 
                    JavaScriptString2("'" + filename + "@RowIndex=" + e.Row.RowIndex.ToString() + "'");            
            }
        }
    </script>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <asp:GridView ID="GridView1" 
                runat="server" 
                AutoGenerateColumns="False" 
                OnRowCommand="GridView1_RowCommand" 
                OnRowDataBound="GridView1_RowDataBound">
                <Columns>
                    <asp:BoundField DataField="Id" HeaderText="ID" />
                    <asp:BoundField DataField="A-Tag" HeaderText="方法1" 
                        HtmlEncode="False" />
                    <asp:TemplateField HeaderText="方法2">
                        <ItemTemplate>
                            <asp:LinkButton ID="LinkButton1" 
                                runat="server" 
                                Text='<%# Eval("Filename") %>'
                                CommandName='<%# Eval("Id") %>'
                                CommandArgument='<%# Eval("Filename") %>'
                                OnClientClick='<%# JavaScriptString1((string)Eval("Filename")) %>'>
                            </asp:LinkButton>
                        </ItemTemplate>
                    </asp:TemplateField>
                </Columns>
            </asp:GridView>
        </div>
        <asp:Label ID="Label1" runat="server"></asp:Label>
        <br />
        <asp:Label ID="Label2" runat="server"></asp:Label>
        <input type="hidden" name="HiddenField1" id="HiddenField1" value="" runat="server" />
        </form>
    </body>
    </html>
    <script type="text/javascript">
        <!--
        var theForm = document.forms['form1'];
        if (!theForm) {
            theForm = document.form1;
        }
        function PostBack(filename) {
            if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
                theForm.HiddenField1.value = filename;
                theForm.submit();
            }
        }
        //-->
    </script>
    
    • 回答としてマーク sk7474 2009年5月22日 9:04
    2009年5月13日 14:46

すべての返信

  • TemplateField内にLinkButtonを配置してCommandNameを設定しRowCommandイベントで捕捉出来ないか試行しましたが上手くいきませんでした。
    LinkButtonを使う方向で良いと思いますが、どのように上手くいかなかったのでしょうか?
    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    2009年5月12日 5:18
    モデレータ
  • trapemiyaさま

    ご返信ありがとうございます。
    説明不足で申し訳ありません。
    以下のようなコードで実行した結果、LinkButtonクリック時にRowCommandイベントに到達することができませんでした。


    <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" 
        Font-Bold="True" ShowHeader="False" 
        BorderColor="Black">
        <Columns>
            <asp:BoundField HeaderText="A" HtmlEncode="false" DataField="Ext" >
                <ItemStyle BorderColor="Black" Wrap="False" HorizontalAlign="Center" Width="60px"/>
            </asp:BoundField>
            <asp:TemplateField HeaderText="B">
                <ItemTemplate>
                <asp:LinkButton ID="LinkButton1" runat="server" CommandName="FileNameClick">
                    <%#DataBinder.Eval(Container.DataItem, "FileName")%></asp:LinkButton>
                </ItemTemplate>
                <ItemStyle BorderColor="Black" width="700px" HorizontalAlign="Left"/>
            </asp:TemplateField>
            <asp:BoundField HeaderText="C" HtmlEncode="false" DataField="FD">
                <ItemStyle BorderColor="Black" Wrap="False" HorizontalAlign="Center" Width="60px"/>
            </asp:BoundField>
            <asp:BoundField HeaderText="D" DataField="UploadCount">
                <ItemStyle BorderColor="Black" Wrap="False" HorizontalAlign="Center" Width="50px"/>
            </asp:BoundField>
            <asp:BoundField HeaderText="E" DataField="DownladCount" >
                <ItemStyle BorderColor="Black" Wrap="False" HorizontalAlign="Center" Width="50px"/>
            </asp:BoundField>
            <asp:BoundField HeaderText="F" DataField="Date" >
                <ItemStyle BorderColor="Black" Wrap="False" HorizontalAlign="Center" Width="200px"/>
            </asp:BoundField>
       </Columns>
    </asp:GridView>
    Protected Sub GridView1_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles GridView1.RowCommand
        If e.CommandName = "FileNameClick" Then
            Dim intTotal As Integer = 0
            Dim intToday As Integer = 0
            If Not Text() Then
    			'処理
            End If
        End If
    End Sub
    なおGridView1_RowDataBoundやGridView1_RowCreated内で(意味があるとは思えませんでしたが)CommandNameを
    設定し直してみたりもしたのですがクリック時にRowCommandに到達できませんでした。
    お手数ですがアドバイスなどよろしくお願い致します。
    2009年5月12日 5:32
  • 追加したLinkButtonにOnClickイベント追加してみてはいかがでしょうか?
    <asp:LinkButton ID="LinkButton1" runat="server" CommandName="FileNameClick" OnClick="LinkButton1_Click">

    コード
    Protected Sub LinkButton1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles LinkButton1.Click
       '処理
    End Sub

    これで要件は満たすでしょうか?

    VBは詳しくありませんので、コード記述に不備があるかもしれません。。


    MCITP(Database Developer/Database Administrator) MCTS(SQL Server 2005/Web Applications)
    • 回答としてマーク sk7474 2009年5月22日 9:06
    2009年5月12日 6:12
  • 追加したLinkButtonにOnClickイベント追加してみてはいかがでしょうか?
    <asp:LinkButton ID="LinkButton1" runat="server" CommandName="FileNameClick" OnClick="LinkButton1_Click">

    コード
    Protected Sub LinkButton1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles LinkButton1.Click
       '処理
    End Sub



    ノブヒデさま

    ご回答ありがとうございます。
    上記、アドバイスいただきましたOnClickイベントを追加して試行してみたいと思います。
    ありがとうございました。
    2009年5月12日 6:42
  • OnClickイベントでも良いんですが、たぶん、どの行のボタンがクリックされたかが知りたいのではないかと思います。
    その場合は、GridViewのRowCreatedイベントとRowCommandイベントを使用して下さい。

    Protected 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 linkBtn As LinkButton
    
          linkBtn = CType(e.Row.FindControl("LinkButton1"), LinkButton)
          linkBtn.CommandArgument = Clickされた時に渡したいもの
        End If
    
    End Sub
    
    
    Protected Sub GridView1_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles GridView1.RowCommand
    
       Select Case e.CommandName
          Case "FileNameClick"
             何かの処理。RowCreatedイベントでセットした値はe.CommandArgumentで
             手に入る。
          Case Else
       End Select
    
    End Sub



    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    • 回答としてマーク sk7474 2009年5月22日 9:06
    2009年5月12日 6:55
    モデレータ
  • 以下のようなコードで実行した結果、LinkButtonクリック時にRowCommandイベントに到達することができませんでした。


    <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" 
    
        Font-Bold="True" ShowHeader="False" 
    
        BorderColor="Black">
    もしかして、<asp:GridView> タグ内に以下記述が不足しているので到達しないと言う事でしょうか??
     OnRowCommand="GridView1_RowCommand"

    MCITP(Database Developer/Database Administrator) MCTS(SQL Server 2005/Web Applications)
    • 回答としてマーク sk7474 2009年5月22日 9:06
    2009年5月12日 7:18
  • OnClickイベントでも良いんですが、たぶん、どの行のボタンがクリックされたかが知りたいのではないかと思います。
    その場合は、GridViewのRowCreatedイベントとRowCommandイベントを使用して下さい。



    trapemiyaさま

    度々のご回答ありがとうございます。
    ご教授いただきましたとおりRowCreatedイベントとRowCommandイベントを以下のようにして試行してみました。

    Protected 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 linkBtn As LinkButton
    
            linkBtn = CType(e.Row.FindControl("LinkButton1"), LinkButton)
            ' 選択行インデックス設定
            linkBtn.CommandArgument = e.Row.RowIndex
        End If
    End Sub
    
    Protected Sub GridView1_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles GridView1.RowCommand
    
        Dim intTotal As Integer = 0
        Dim intToday As Integer = 0
        Dim index As Integer
    
        index = e.CommandArgument
    
        Select Case e.CommandName
            Case "FileNameClick"
                AccessCountUpdate(True, DocListPath, ACCESS_COUNT_FILE & "_" & index, intTotal, intToday)
            Case Else
    
        End Select
    End Sub
       



    試行した結果、RowCreatedイベントでは期待通りにCommandArgument に行インデックスが設定されることを確認できましたが
    LinkButton(TemplateField内のLinkButton)をクリックした際にRowCommandイベントへ到達することができませんでした。
    なおGridViewの定義は前回提示したままの状態で変更しておりません。
    FileNameをバインドしているLinkButtonをクリックした場合に、RowCommandイベントが発生するものと考えていますが認識に間違いはありませんでしょうか?
    お手数ですが引き続きご教授のほどよろしくお願い致します。
    2009年5月12日 7:25
  • FileNameをバインドしているLinkButtonをクリックした場合に、RowCommandイベントが発生するものと考えていますが認識に間違いはありませんでしょうか?
    間違いありません。私も勘違いしておりましたが、結局、RowCommandイベントが発生しないというのが問題のようですね。RowCommandイベントに到達しないというのは、そこにブレークポイントをセットしても止まらないということなのでしょうか? 例えば、
    System.Diagnostics.Debug.WriteLine("LinkButton Click! " & e.CommandArgument)
    の一行をRowCommandイベントハンドラに追加してデバッグ実行しても、出力ウインドウに表示されないのでしょうか?
    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    • 回答としてマーク sk7474 2009年5月22日 9:05
    2009年5月12日 7:49
    モデレータ
  • もしかして、<asp:GridView> タグ内に以下記述が不足しているので到達しないと言う事でしょうか??
     OnRowCommand="GridView1_RowCommand"

    MCITP(Database Developer/Database Administrator) MCTS(SQL Server 2005/Web Applications)


    ノブヒデさま

    何度もご回答ありがとうございます。
    ご指摘の通り<asp:GridView> 内にOnRowCommand="GridView1_RowCommand"がありませんでしたので追加後に試行いたしましたが
    またしてもRowCommandイベントに到達することができませんでした。
    そのほかになにかお気づきの点がありましたらご教授のほどよろしくお願い致します。
    2009年5月12日 8:01
  • 間違いありません。私も勘違いしておりましたが、結局、RowCommandイベントが発生しないというのが問題のようですね。RowCommandイベントに到達しないというのは、そこにブレークポイントをセットしても止まらないということなのでしょうか? 例えば、
    System.Diagnostics.Debug.WriteLine("LinkButton Click! " & e.CommandArgument)
    の一行をRowCommandイベントハンドラに追加してデバッグ実行しても、出力ウインドウに表示されないのでしょうか?
    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/

    trapemiyaさま

    ご回答ありがとうございます。
    言葉足らずでしたがご認識の通り、今までの試行はRowCommandイベントにブレークポイントを設定した状態で到達できていないことを確認しておりました。
    上記デバッグ出力を追加後、試行いたしましたがこちらも出力ウィンドウに表示されないことを確認いたしました。
    ご教授いただきましたとおり本来であればRowCommandイベントに到達するものができていない場合、そのほかに確認すべきことはありますでしょうか?
    お手数ですがお気づきのことがありましたらご教授ください。よろしくお願い致します。
    2009年5月12日 8:20
  • またしてもRowCommandイベントに到達することができませんでした。
    そのほかになにかお気づきの点がありましたらご教授のほどよろしくお願い致します。

    クローバー様

    VBに詳しくないので、勉強がてらサンプルを作成してみましたが、正常にイベントに到達しました。
    サンプルは以下です。
    開発環境:VS2005 VB Webアプリケーション

    -------------- aspx ここから  --------------
    <%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Default.aspx.vb" Inherits="Sample._Default" %>

    <!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>無題のページ</title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" Font-Bold="True" ShowHeader="False"
            BorderColor="Black" OnRowCommand = "GridView1_RowCommand">
                <Columns>
                    <asp:TemplateField>
                        <ItemTemplate>
                            <asp:LinkButton ID="LinkButton1" runat="server" CommandName="FileNameClick">
                            <%#DataBinder.Eval(Container.DataItem, "FileName")%></asp:LinkButton>
                        </ItemTemplate>
                    </asp:TemplateField>
               </Columns>
            </asp:GridView>
        </div>
        </form>
    </body>
    </html>
    -------------- aspx ここまで  --------------

    -------------- aspx.vb ここから  -------------
    Partial Public Class _Default
        Inherits System.Web.UI.Page

        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            If Not IsPostBack Then
                Dim dt As DataTable
                Dim dr As DataRow
                dt = New DataTable()
                dt.Columns.Add("FileName", System.Type.GetType("System.String"))
                dr = dt.NewRow()
                dr("FileName") = "FileName:1"
                dt.Rows.Add(dr)

                GridView1.DataSource = dt
                GridView1.DataBind()
            End If
        End Sub

        Protected Sub GridView1_RowCommand(ByVal sender As System.Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles GridView1.RowCommand
            Response.Redirect("http://msdn.microsoft.com/ja-jp/default.aspx")
        End Sub
    End Class
    -------------- aspx.vb ここまで  -------------

    何か参考になれば幸いです。


    MCITP(Database Developer/Database Administrator) MCTS(SQL Server 2005/Web Applications)
    • 回答としてマーク sk7474 2009年5月22日 9:05
    2009年5月12日 11:13
  • > 各カラムは<A href ~ /A>で別画面で特定のファイルを表示、保存できるようにしています。

    とのことですが、それで何故、

    > TemplateField内にLinkButtonを配置してCommandNameを設定しRowCommandイベントで捕捉出来
    > ないか試行しましたが上手くいきませんでした。

    という話になるのでしょうか?

    LinkButton は外観が違うだけで Button と同じで、ハイパーリンク(<A href ~ /A>)の役目
    は果たせないと思いますが。

    各カラム、セルの中身はハイパーリンク(<A href ~ /A>)のままにしておいて、それがクリック
    されたとき href で指定したページに飛ぶのと同時に、どのカラム/セルがクリックされたかサーバー
    側で取得したいということですか?

    そうであれば、GridView の各 Cell の OnClick 属性に JavaScript の function を設定して
    input type="hidden" の value 属性に必要な情報を設定し、form を submit してやるという方
    法が考えられます。

    見当違いでしたら失礼しました。

    • 回答としてマーク sk7474 2009年5月22日 9:05
    2009年5月12日 14:41
  • > 各カラムは<A href ~ /A>で別画面で特定のファイルを表示、保存できるようにしています。

    とのことですが、それで何故、

    > TemplateField内にLinkButtonを配置してCommandNameを設定しRowCommandイベントで捕捉出来
    > ないか試行しましたが上手くいきませんでした。

    という話になるのでしょうか?

    LinkButton は外観が違うだけで Button と同じで、ハイパーリンク(<A href ~ /A>)の役目
    は果たせないと思いますが。

    各カラム、セルの中身はハイパーリンク(<A href ~ /A>)のままにしておいて、それがクリック
    されたとき href で指定したページに飛ぶのと同時に、どのカラム/セルがクリックされたかサーバー
    側で取得したいということですか?

    そうであれば、GridView の各 Cell の OnClick 属性に JavaScript の function を設定して
    input type="hidden" の value 属性に必要な情報を設定し、form を submit してやるという方
    法が考えられます。

    見当違いでしたら失礼しました。


    SurferOnWwwさま

    ご返信ありがとうございます。
    今まではDataTableに<A href ~ /A>を設定してGridViewにバインドしてファイルの表示、保存をしていましたが
    ファイルの表示、保存時に何度そのファイルが表示されたかなどのカウントを行う必要が出てきたため
    RowCommandイベントでそのほか(ファイルの表示、保存)の処理を行おうと考えました。
    なお以下のGridViewの定義とDataTable内に<A href ~ /A>を設定、GridViewにバインドでファイルの表示、保存を行うことはできています。
    (ご指摘いただいた件とは別なのかもしれませんが。)

    <asp:TemplateField HeaderText="ファイル名">
        <ItemTemplate>
            <asp:LinkButton ID="LinkButton1" runat="server" CommandName="FileNameClick">
                <%#DataBinder.Eval(Container.DataItem, "FileName")%>
            </asp:LinkButton>
        </ItemTemplate>
        <ItemStyle BorderColor="Black" width="700px" HorizontalAlign="Left"/>
    </asp:TemplateField>
    



    JavaScriptでの方法は存じ上げませんでした。
    JavaScriptはまったく詳しくないのでご提示いただきました内容を確認して試行してみたいと思います。
    ありがとうございました。

    2009年5月13日 0:14
  • ノブヒデさま

    何度もご回答いただきありがとうございます。
    サンプルコード参考にさせていただきます!

    2009年5月13日 0:15
  • ご教授いただきましたとおり本来であればRowCommandイベントに到達するものができていない場合、そのほかに確認すべきことはありますでしょうか?
    お手数ですがお気づきのことがありましたらご教授ください。よろしくお願い致します。
    不思議ですね。

    あとやってみることとしては、Temporary ASP.NET Filesの中身を削除してソリューションのリビルドぐらいでしょうか・・・
    Temporary ASP.NET Filesの場所は小野さんの情報を参考にして下さい。

    VISTAとVS2008とTemporary ASP.NET Files
    http://dotnetfan.org/blogs/dotnetfanblog/archive/2008/03/28/2742.aspx

    それでもダメな場合、LinkButtonではなくButtonの場合や、新たなaspxでテストすると何か気付かれることがあるかもしれません。
    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    2009年5月13日 0:40
    モデレータ
  • あと、GridViewのEnableViewStateを確認してみて下さい。trueにするとRowCommandが発動するようになったという情報がありました。
    私としては直接関係ない気もするのですが、それが何かのトリガになってどこかが再生成されるのかもしれません。そういう意味では私のすぐ上の書き込みと同じなんですが・・・
    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    2009年5月13日 1:19
    モデレータ
  • あとやってみることとしては、Temporary ASP.NET Filesの中身を削除してソリューションのリビルドぐらいでしょうか・・・
    Temporary ASP.NET Filesの場所は小野さんの情報を参考にして下さい。

    VISTAとVS2008とTemporary ASP.NET Files
    http://dotnetfan.org/blogs/dotnetfanblog/archive/2008/03/28/2742.aspx

    それでもダメな場合、LinkButtonではなくButtonの場合や、新たなaspxでテストすると何か気付かれることがあるかもしれません。
    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/


    trapemiyaさま

    ご返信ありがとうございます。
    とりあえずご教授いただきましたTemporary ASP.NET Files以下のファイル削除、リビルドを試してみます。
    それでも上手くいかない場合は、色々とButtonにしてみるなりして差異を確認していきたいと思います。

    >みなさま
    この度は何度もご親切に教えていただきありがとうございました。
    知らなかったこともたくさんありましたので大変勉強になりました。
    また機会がありましたらよろしくお願い致します。
    2009年5月13日 1:21
  • 大外しだったらごめんなさい。

    RowCommand イベントには到達していないとして、その時にポストバックは発生しているのでしょうか?(Load イベントを通過しているかとか)
    ちゃんと LinkButton で生成されたリンクをクリックしているのですよねぇ。各セルの <A href ~ /A> ではなく。
    • 回答としてマーク sk7474 2009年5月22日 9:04
    2009年5月13日 1:22
  • totojoさま

    ご返信ありがとうございます。
    今更ながらHTMLを確認したのですが以下のような状態になっており仰るとおり今までは各セルの <A href ~ /A>をクリックしていたような気がします・・・。

    <td align="left" style="border-color:Black;width:700px;">
            <a id="GridView1_ctl03_LinkButton1" href="javascript:__doPostBack('GridView1$ctl03$LinkButton1','')">
    	<A HREF='TEST\AccessCount.txt' TARGET='_blank'> AccessCount.txt </A>
    	</a>
    </td>
    そのためDataTableにはファイル名だけを設定して試行してみた所、RowCommand イベントに到達することを確認できました。
    DataTableに<A href ~ /A>を設定してバインドしてもこの場合、RowCommand イベントは発生しないのですね。
    私の知識不足のためみなさまには大変ご迷惑をおかけしてしまいました。

    ただRowCommandイベントでどうやって<A href ~ /A>のように別ウィンドウのWebフォームにファイルを表示するか
    という問題が発生してしまいましたが・・・。

    とりあえずみなさまからのたくさんのアドバイス、ご指摘により一歩前進できました。
    ありがとうございます。
    できれば別ウィンドウでWebフォームからファイルを表示、保存する方法をご存知であれば引き続きご教授をよろしくお願い致します。
    2009年5月13日 2:36
  • なるほど。そういうことでしたか。とりあえず、RowCommandイベントハンドラに以下のように書いてみて下さい。

    ClientScript.RegisterStartupScript(Me.GetType(), _
                      "hogeKey", _
                      "<script type='text/javascript'>window.open('Hoge.aspx'," & _
                      "'hogeName'," & _
                      "'width=300,height=300')</script>")

    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    • 回答としてマーク sk7474 2009年5月22日 9:04
    2009年5月13日 4:52
    モデレータ
  • > 今まではDataTableに<A href ~ /A>を設定してGridViewにバインドしてファイルの表示、保存をしていましたが
    > ファイルの表示、保存時に何度そのファイルが表示されたかなどのカウントを行う必要が出てきたため
    > RowCommandイベントでそのほか(ファイルの表示、保存)の処理を行おうと考えました。

    色々方法はありますが、とりあえず以下の方法をご紹介します。(1) は先のレスで紹介した方法です。

    (1) クローバーさんが最初に行ったように A タグを使用。その A タグを格納する GridView の各 Cell の
      OnClick 属性に JavaScript を設定して input type="hidden" の value 属性にどのファイルが選択さ
      れたか等の必要な情報を設定し、form を submit してやる方法。

    (2) LinkButton を使用。LinkButton の Text には A タグでなくファイル名の文字列のみを設定。ファイル
      を開くためには OnClientClick プロパティに JavaScript(window.open) を設定。同時に RowCommand
      イベントでどのファイルが選択されたか等の情報を取得。

    ご参考までに、検証に使ったコードもアップしておきます。

    <%@ Page Language="C#" %>
    <%@ Import Namespace="System.Data" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <script runat="server">
        protected DataTable CreateDataTable()
        {
            DataTable dt = new DataTable();
            DataRow dr;
    
            dt.Columns.Add(new DataColumn("Id", typeof(int)));
            dt.Columns.Add(new DataColumn("A-Tag", typeof(string)));
            dt.Columns.Add(new DataColumn("Filename", typeof(string)));
    
            for (int i = 0; i < 10; i++)
            {
                dr = dt.NewRow();
                dr["Id"] = i;
                dr["A-Tag"] = "<a href=\"../Data/Excel.xls\" target='_blank'>Excel.xls</a>";
                dr["Filename"] = "Excel.xls";
                dt.Rows.Add(dr);
            }
            return dt;
        }
    
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                GridView1.DataSource = CreateDataTable();
                GridView1.DataBind();
            }
            else
            {
                // 方法1: 
                // A タグを使用。その cell の onclick 属性に JavaScript を設定。JavaScript で HiddenField の
                // Value 属性にどのファイルが選択されたか等の必要な情報をセットし、form を submit して取得。
                Label1.Text = HiddenField1.Value;
                Label2.Text = String.Empty;
            }
        }
    
        protected string JavaScriptString1(string filename)
        {
            return String.Format("window.open('../Data/{0}', '_blank')", filename);
    
        }
    
        protected string JavaScriptString2(string filename)
        {
            return String.Format("javascript:PostBack({0});", filename);
        }
            
        protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
        {
            // 方法2: 
            // LinkButton を使用し、OnClientClick プロパティに window.open を設定して選んだファイルを開く。
            // 同時に RowCommand イベントでどのファイルが選択されたか等の情報を取得
            Label1.Text = String.Empty;
            Label2.Text = String.Format("Id: {0}, Filename: {1}", e.CommandName, e.CommandArgument.ToString());
        }
    
        protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                string filename = ((LinkButton)e.Row.Cells[2].FindControl("LinkButton1")).Text;
                e.Row.Cells[1].Attributes["onclick"] = 
                    JavaScriptString2("'" + filename + "@RowIndex=" + e.Row.RowIndex.ToString() + "'");            
            }
        }
    </script>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <asp:GridView ID="GridView1" 
                runat="server" 
                AutoGenerateColumns="False" 
                OnRowCommand="GridView1_RowCommand" 
                OnRowDataBound="GridView1_RowDataBound">
                <Columns>
                    <asp:BoundField DataField="Id" HeaderText="ID" />
                    <asp:BoundField DataField="A-Tag" HeaderText="方法1" 
                        HtmlEncode="False" />
                    <asp:TemplateField HeaderText="方法2">
                        <ItemTemplate>
                            <asp:LinkButton ID="LinkButton1" 
                                runat="server" 
                                Text='<%# Eval("Filename") %>'
                                CommandName='<%# Eval("Id") %>'
                                CommandArgument='<%# Eval("Filename") %>'
                                OnClientClick='<%# JavaScriptString1((string)Eval("Filename")) %>'>
                            </asp:LinkButton>
                        </ItemTemplate>
                    </asp:TemplateField>
                </Columns>
            </asp:GridView>
        </div>
        <asp:Label ID="Label1" runat="server"></asp:Label>
        <br />
        <asp:Label ID="Label2" runat="server"></asp:Label>
        <input type="hidden" name="HiddenField1" id="HiddenField1" value="" runat="server" />
        </form>
    </body>
    </html>
    <script type="text/javascript">
        <!--
        var theForm = document.forms['form1'];
        if (!theForm) {
            theForm = document.form1;
        }
        function PostBack(filename) {
            if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
                theForm.HiddenField1.value = filename;
                theForm.submit();
            }
        }
        //-->
    </script>
    
    • 回答としてマーク sk7474 2009年5月22日 9:04
    2009年5月13日 14:46
  • こんにちは。中川俊輔です。

    皆様、たくさんの詳細な回答、本当にありがとうございます。

    クローバーさん、フォーラムのご利用ありがとうございます。
    勝手ながら、有用な情報と思われる回答へ回答マークをつけさせていただきました。

    今後ともフォーラムをよろしくお願いします。
    それでは!
    マイクロソフト株式会社 フォーラム オペレータ 中川 俊輔
    2009年5月22日 9:10