C# + Visual Studio 2008 開発メモ
ひさしぶりにVisual StudioでC#を使っています。次回のために、今回詰まったところをメモ。
ListはSystem.Collections.Generic
まず、つまらないミスの話から。
List
using System.Collections.Generic;
System.Collectionsだけじゃダメなんですね。
ジェネリクスはC#2.0から使えるはずなのに、なぜだろう……もしかして今書いてるコードはC#2.0以前なのか? なんて、10分くらい悩みました。考えすぎでした。
GridView内コントロールのVisibleとEnableをデータバインドで制御
実現したいこと
GridViewのタテ一列で、ある行のデータを登録済のときは「登録済」というラベルを表示し、登録前のときは「登録」ボタンを表示する。GridViewにバインドするデータソースには、RegistFlagというbool型の値がある。RegistFlagがTrueなら登録済、Falseなら登録前である。
方法
- ボタンとラベルの表示を切り替えたい列をTemplateFieldにする。
- aspxのデザインビューで、GridViewのTemplateFieldを編集する。
- TemplateFieldにした列を表示し、登録済ラベルのコントロールと登録ボタンのコントロールを並べて配置する。
- 2つのコントロールのデータバインド項目を編集する。
登録済ラベルの設定
(bool)Eval("RegistFlag") // RegistFlagがTrueなら表示
登録ボタンの設定
(bool)Eval("RegistFlag")==false // RegistFlagがfalseなら表示
これでOK。どっとねっとふぁんBlogさんの記事が参考になりました。
dotnetfan.org - このウェブサイトは販売用です! - dotnetfan リソースおよび情報
昨年Visual StudioとC#を使ったときは、この方法を知らなかったので、コードビハインドで書いていました。
if(RegistFlag) { SubmitRegist.Visible = true // 登録ボタン AfterRegist.Visible = false // 登録済ラベル } else { SubmitRegist.Visible = false AfterRegist.Visible = true }
みたいな。上では単純化して書いたけど、本当はたしか、RowsとCellsとFindControlを使って行数文だけforで回し、Visibleの値を設定する必要があったと思う。その上、RegisFlagの値を取得するために、次の手順が必要でした。
- RegistFlagをバインドした列を新規に作る。
- その列をTemplateFieldにする。
- 列のVisibleをFalseにする。
RegistFlagは、表示制御で使うためにバインドしたい。しかし、GridViewには表示したくない。だから、こうする必要がありました。単純にバインドしてFalseにすると値が渡らないらしいので、わざわざTemplateFieldにしてからFalseにしていたという。
こんな辛い記述から解放されました。
GridView内のボタンを使って引数を渡す
- GridViewのプロパティを編集して、RowCommandイベントで実行するメソッドを指定する。GridView名_RowCommadってかんじでOK。
- ButtonFieldをTemplateFieldにする。
- aspxのデザインビューで、GridViewのTemplateFieldを編集する。
- TemplateFieldにした列を表示し、ボタンのデータバインド項目を編集する。
ボタンのデータバインド項目に、e.CommandArgumentというパラメータがあるので、ボタンをクリックしたときに渡したい値をバインドします。たとえば、UserIDとか。
これによって、GridView名_RowCommadメソッド内で、バインドに設定したUserIDを取得できます。具体的には、引数のイベントオブジェクト(たとえばe)を使って、e.CommandArgumentでUserIDの値を取得します。
この方法を使えば、UserIDをHiddenFieldで渡さなくてもOKです。
GridView内のボタンをクリックしたとき選択行を特定する方法
たぶんいくらでもやり方はあるのだろうけど、初心者(私)でも思いつくのは、次の2つの方法です。
キーとなるIDを渡す or 行番号を渡す
さて、どっち? 使い分けはこうです。
- 選択行を特定した後、キーとなるIDのみ使いたいとき
- 上で書いたように、ボタンクリックイベントの引数として、キーとなるIDを渡せばよいと思います。たとえば、UserIDのみ受け取って、ボタンクリック後にもう一度データベースを検索する場合。
- 選択行を特定した後、キーとなるIDおよび行番号を使いたいとき
- ボタンクリックイベントの引数として、行番号を渡します。ボタンクリックイベントの引数としてIDを渡してしまうと、行番号を渡すことができなくなります。
注意するのは、行番号を渡したい場合、ボタンを配置する列をTemplateFieldに変換せず、ButtonFieldのまま使うこと。なぜなら、ButtonFieldだと、デフォルトで引数に行番号が入るためです。TemplateFieldにしてしまうと、行番号を取得できない。
e.CommandArgumentに値をバインドして引数にできるとわかって、喜んで実装したものの、実は引数だけでなく行番号も必要だった……というのが、私がやってしまったパターンです。TemplateFieldを廃してButtonFieldを作り直し、e.CommandArgumentで取れる値をIDでなく行番号と想定してメソッドを書き直す、といった手間がかかりました。
特に、最後のこの件は、しばらくたったら忘れてまたやりそうなので、メモに残しておきます。