none
GridViewのCommandFieldのボタンを無効化したい RRS feed

  • 質問

  • 環境:VS2008、2005 C# ASP.NET2.0

    GridViewのCommandFieldカラムでレコードの削除ボタンを実装しています。
    削除できない行があらかじめわかっているので、
    その行だけ削除ボタンを無効化したいのですが可能でしょうか。
    宜しくお願い致します。
    2009年11月27日 7:36

回答

  • CommandFieldのままだとできるとしても結構面倒な気がします。
    削除ボタンを無効にするのがその行にバインドされているデータの値とかからで制御できるのなら、
    CommandFieldをTemplateフィールドに変換して、削除ボタンのスマートタグでDataBindingsの
    編集を設定し、削除ボタンのVisibleやEnabledプロパティをバインドする値で制御することが可能です。

    参考:
    http://dotnetfan.org/blogs/dotnetfanblog/articles/692.aspx
    あおい情報システム株式会社 小野修司(どっとねっとふぁん)
    • 回答としてマーク Myon 2009年11月28日 16:08
    2009年11月27日 8:44
  • 菊池です

     まず CommandField を作って、それをTemplateFieldに変換してみてはどうでしょうか。(Visual StudioのGridViewの行の設定ダイアログから実行できます)

    > また、Button.CommandName="Edit"としても編集モードに
    >なってくれるわけでもないようです。

     基本的にはそれでなるはずですが、LoadでIsPostBackの時にDataBindをしない様に制御してないのではないでしょうか。
    #Editで編集モードになった後で DataBindをした結果モードがリセットされている

     最初の段階で欲張らずに基本動作ができてからテンプレート列に変換を使って細部を詰めていく方がいいでしょう。


    Kazuhiko Kikuchi
    • 回答としてマーク Myon 2009年11月28日 16:08
    2009年11月27日 13:11
  • > テンプレートクラス内でEditボタンを押したら
    > 編集モードに切り替えようと思っており、
    > 以下のようなコードを書きました。

    そのようなコードを書く必要はないと思いますけど。

    たぶん、以下のような CommandField ができていると思いますが、

    <asp:CommandField ShowDeleteButton="True" ShowEditButton="True"
        ShowSelectButton="True" />

    それを、デザイン画面の「フィールド」メニューから[このフィールドを TemplateField に変換します。]を
    クリックして自動変換すると、

    <asp:TemplateField ShowHeader="False">
        <ItemTemplate>
            <asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="False"
                CommandName="Edit" Text="編集"></asp:LinkButton>
            &nbsp;<asp:LinkButton ID="LinkButton2" runat="server" CausesValidation="False"
                CommandName="Select" Text="選択"></asp:LinkButton>
            &nbsp;<asp:LinkButton ID="LinkButton3" runat="server" CausesValidation="False"
                CommandName="Delete" Text="削除"></asp:LinkButton>
        </ItemTemplate>
        <EditItemTemplate>
            <asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="True"
                 CommandName="Update" Text="更新"></asp:LinkButton>
            &nbsp;<asp:LinkButton ID="LinkButton2" runat="server" CausesValidation="False"
                 CommandName="Cancel" Text="キャンセル"></asp:LinkButton>
        </EditItemTemplate>
    </asp:TemplateField>

    というようになります。それでどうすればよいかわかりますよね?

    • 回答としてマーク Myon 2009年11月28日 16:08
    2009年11月27日 14:02
  • > IsPostBackに関わらずデータはバインドしてしまっていますが、
    > そうしないとPostBack後にCommandFieldのボタン自体がなくなってしまいます。
    > Page_Loadでのバインドの処理はどのように記述するのが正しいのでしょうか。

    もともとのデータソースは何ですか? たとえば、SQL Server なら SqlDataSource を利用すればバインドは
    自動的にやってくれますし、Delete, Insert, Update 処置のためのコードも自動生成してくれますけど。

    データソースが DataTable で、それを更新するばあいは、その DataTable を Delete, Insert, Update する
    コードを実装したクラスを作成し、それを ObjectDataSource の TypeName などに設定し、 GridView の
    DataSourceID に設定するのが普通と思います。

    一体、データソースは何で、それをどうやって GridView に設定しているのでしょう? そもそも、最初の質
    問の CommandField を使った状態で、意図したように動いているのでしょうか?


    #ところで、質問の内容が変わってきているようですが、スレッドの表題「GridViewのCommandFieldのボタン
     を無効化したい」の件はもう忘れていいのでしょうか?

    • 回答としてマーク Myon 2009年11月28日 16:08
    2009年11月28日 10:23

すべての返信

  • CommandFieldのままだとできるとしても結構面倒な気がします。
    削除ボタンを無効にするのがその行にバインドされているデータの値とかからで制御できるのなら、
    CommandFieldをTemplateフィールドに変換して、削除ボタンのスマートタグでDataBindingsの
    編集を設定し、削除ボタンのVisibleやEnabledプロパティをバインドする値で制御することが可能です。

    参考:
    http://dotnetfan.org/blogs/dotnetfanblog/articles/692.aspx
    あおい情報システム株式会社 小野修司(どっとねっとふぁん)
    • 回答としてマーク Myon 2009年11月28日 16:08
    2009年11月27日 8:44
  • ご回答ありがとうございました。
    Templateフィールドは使ったことがないのですが、
    可能だということがわかってきました。

    また新たな疑問が次々に出てきたのですがよろしいでしょうか。
    勉強のため、CommandFieldと同じようなものをテンプレートで作ってみようとしています。

    テンプレートクラス内でEditボタンを押したら
    編集モードに切り替えようと思っており、
    以下のようなコードを書きました。

      void buttonEdit_Command( object sender, CommandEventArgs e )
      {
       Button buttonEdit = sender as Button;
       if( buttonEdit == null ) return;

       GridViewRow gridViewRow = buttonEdit.NamingContainer as GridViewRow;
       if( gridViewRow == null ) return;

       // 編集モードに切り替える。
       _grid.EditIndex = gridViewRow.RowIndex;

      }


    Page_loadでデータをバインドしているのですが、
    上記のコードだとEditボタンを2回押してはじめて編集モードになります。
    どうしてでしょうか。


    ITemplate派生クラスの中で、GridViewのインスタンスを
    取得することは可能でしょうか。


    Button.CommandName
    というのはどうやって使えばよいのでしょうか。
    Button.CommandName="Cancel"とするとRowCancelingEditイベントが
    発生するようなのですが、実際に編集モードが
    通常モードに戻るわけでもないようです。
    また、Button.CommandName="Edit"としても編集モードに
    なってくれるわけでもないようです。

    以上、大変お手数をおかけしますが、
    御教授いただけないでしょうか。
    宜しくお願い致します。




    2009年11月27日 10:11
  • 菊池です

     まず CommandField を作って、それをTemplateFieldに変換してみてはどうでしょうか。(Visual StudioのGridViewの行の設定ダイアログから実行できます)

    > また、Button.CommandName="Edit"としても編集モードに
    >なってくれるわけでもないようです。

     基本的にはそれでなるはずですが、LoadでIsPostBackの時にDataBindをしない様に制御してないのではないでしょうか。
    #Editで編集モードになった後で DataBindをした結果モードがリセットされている

     最初の段階で欲張らずに基本動作ができてからテンプレート列に変換を使って細部を詰めていく方がいいでしょう。


    Kazuhiko Kikuchi
    • 回答としてマーク Myon 2009年11月28日 16:08
    2009年11月27日 13:11
  • > テンプレートクラス内でEditボタンを押したら
    > 編集モードに切り替えようと思っており、
    > 以下のようなコードを書きました。

    そのようなコードを書く必要はないと思いますけど。

    たぶん、以下のような CommandField ができていると思いますが、

    <asp:CommandField ShowDeleteButton="True" ShowEditButton="True"
        ShowSelectButton="True" />

    それを、デザイン画面の「フィールド」メニューから[このフィールドを TemplateField に変換します。]を
    クリックして自動変換すると、

    <asp:TemplateField ShowHeader="False">
        <ItemTemplate>
            <asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="False"
                CommandName="Edit" Text="編集"></asp:LinkButton>
            &nbsp;<asp:LinkButton ID="LinkButton2" runat="server" CausesValidation="False"
                CommandName="Select" Text="選択"></asp:LinkButton>
            &nbsp;<asp:LinkButton ID="LinkButton3" runat="server" CausesValidation="False"
                CommandName="Delete" Text="削除"></asp:LinkButton>
        </ItemTemplate>
        <EditItemTemplate>
            <asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="True"
                 CommandName="Update" Text="更新"></asp:LinkButton>
            &nbsp;<asp:LinkButton ID="LinkButton2" runat="server" CausesValidation="False"
                 CommandName="Cancel" Text="キャンセル"></asp:LinkButton>
        </EditItemTemplate>
    </asp:TemplateField>

    というようになります。それでどうすればよいかわかりますよね?

    • 回答としてマーク Myon 2009年11月28日 16:08
    2009年11月27日 14:02

  • Kazuk様、 SurferOnWww様、ご回答ありがとうございます。

    確かにテンプレートに進むのは早すぎたようで、
    CommandFieldの動き自体理解していないようです。

    IsPostBackに関わらずデータはバインドしてしまっていますが、
    そうしないとPostBack後にCommandFieldのボタン自体がなくなってしまいます。
    Page_Loadでのバインドの処理はどのように記述するのが正しいのでしょうか。

    また、CommandFieldを定義するだけで、編集ボタンを押せば
    その行が勝手に編集モードになると思っていたのですが、そうはならないようです。
    以下に記述されているように、RowEditingイベントで
    GridView.EditIndexを設定して、その後に毎回バインドしてやれば
    ちゃんと行が編集モードになってくれるのですが、
    この方法は正しいのでしょうか。
    http://www.daniweb.com/forums/thread101700.html

     

    • 回答としてマーク Myon 2009年11月28日 16:08
    • 回答としてマークされていない Myon 2009年11月28日 16:08
    2009年11月28日 8:19
  • > IsPostBackに関わらずデータはバインドしてしまっていますが、
    > そうしないとPostBack後にCommandFieldのボタン自体がなくなってしまいます。
    > Page_Loadでのバインドの処理はどのように記述するのが正しいのでしょうか。

    もともとのデータソースは何ですか? たとえば、SQL Server なら SqlDataSource を利用すればバインドは
    自動的にやってくれますし、Delete, Insert, Update 処置のためのコードも自動生成してくれますけど。

    データソースが DataTable で、それを更新するばあいは、その DataTable を Delete, Insert, Update する
    コードを実装したクラスを作成し、それを ObjectDataSource の TypeName などに設定し、 GridView の
    DataSourceID に設定するのが普通と思います。

    一体、データソースは何で、それをどうやって GridView に設定しているのでしょう? そもそも、最初の質
    問の CommandField を使った状態で、意図したように動いているのでしょうか?


    #ところで、質問の内容が変わってきているようですが、スレッドの表題「GridViewのCommandFieldのボタン
     を無効化したい」の件はもう忘れていいのでしょうか?

    • 回答としてマーク Myon 2009年11月28日 16:08
    2009年11月28日 10:23
  • ご回答ありがとうございます。
    質問の内容が変わってしまいまして申し訳ありません。
    スレッドの表題についてはこれができないと
    仕様を満たせないので先にお聞きしたのですが、
    最終的にはテンプレートを使って実現しようと考えています。

    CommandField を使った状態でもまだうまく行かず、
    「テンプレート列」や「ObjectDataSource 」についても初めて聞く言葉で、
    実装方法を未だに勉強しながら模索しているところです。

    データソースはMySQLの場合とCSVの場合があります。
    どちらの場合も一度DataTableに読み込んでグリッドにバインドしています。

    行ごとの更新ボタンでSQLを発行させてMySQLを更新しに行くということも考えていますが、
    CSVの事もありますので、
    全部編集してから「OK」ボタンが押されたら
    実際のデータベースやファイルを全行更新でもよいと考えていますが・・・。
    「普通のやり方」がわかっておらず、へんな質問ばかりになっているかと思います。
    申し訳ありませんでした。
    とりあえず、ObjectDataSource の勉強をやってみたいと思います。

    2009年11月28日 11:48