asp.netのWebControlのカスタマイズで、ユーザコントロールっていうものとカスタムコントロールっていうのがあって(他にもあるかもしれないがとりあえずここではこの2つ)両方を開発することがあったのですが、ソースを見てみると、どちらもascxファイルを作ってあった。ただユーザコントロールは派生元がUserControlなのに対し、カスタムコントロールの派生元がLabelなどに置き換わっていました。
なので、ソリューションエクスプローラにascxが表示されるのだけれど、本来のユーザコントロールと違って、カスタムコントロールの場合はソリューションエクスプローラからドラッグ&ドロップでページに配置する使い方はできない。(UserControlから派生していないので)
で、もうちょっと調べてみたらascxのファイルは使っていないみたい。
なんでカスタムコントロールにascxを使ったのかと開発者に聞いてみたら、Webパーツだからとのこと。
使ってもいないファイルなのに(ascxファイルなので使っているaspxと同じように)本番環境に入れてしまうのだけれど、別に有ったからといって問題にならないからいいのかな?
カスタムコントロールのクラスライブラリ化する際にascxのファイルが問題になりそうだけど、今回のものはカスタムコントロールのクラスライブラリ化をしないみたいだし、こちらも問題ないか。
でも、やっぱりなんでascxファイルを作ったか、そのメリットも全然わからない。なんでだろう?
2009年6月6日土曜日
2009年6月5日金曜日
ユーザーコントロールについて
複数のドロップダウンリストがあるユーザコントロールで、親ドロップダウンリスト選択時に子ドロップダウンリストが更新されるユーザコントロールがありました。(ex:県と市町村のドロップダウンがあって、最初は県の一覧のドロップダウンリストのみ選択可能で、県を特定するその県下の市町村がドロップダウンリストにセットされて、市町村ドロップダウンリストが利用可能になるような動きで、県と市町村は親子関係のテーブルでDBに定義されている。)
で、これの親のドロップダウンリストに対するプロパティsetの反映をどうするかで問題になりました。
ASP.NET2.0の動きだと、以下の順番に処理が動きます。
1.aspxページのPage_Load()
2.ascxユーザコントロールのPage_Load()
3.ボタンイベント処理。
DBから読み込み県のドロップダウンリストに県名一覧をセットする処理を、2でにやらせるとなると、非ポストバックのページ読み込み時(aspxのPage_Load())で、県のプロパティセットをしたときには、県のドロップダウンリストがまだできていない状態なので、ドロップダウンのSelectedValueにセットするというのは何かおかしな感じがする。
でも、2.の時点で、県のプロパティの値を見てSelectedValueをセットした場合は、1の処理でプロパティセットをした場合はうまくいくけど、3のボタンイベント処理で、プロパティセットした値は、ドロップダウンリストに反映されなくなる。
で、本当は、1.の前に動くであろう、ユーザコントロール内のドロップダウンリストのInitイベントで、IsPostBackがfalseのときだけ県名のドロップダウンリストに値を詰め込んでおけば、プロパティセット時には、ドロップダウンリストが出来上がっているのでプロパティセット時にドロップダウンリストのSelectedValueに値を詰め込めばよかっただけのような気がします。
つまり、
1.県のドロップダウンリストのInitイベントにてIsPostBackがfalseのときのみ県名一覧をセットする。
2.市のドロップダウンリストのInitイベントでは、選択不可とする。
3.県のプロパティがセットされた場合は、県のドロップダウンリストのSelectedValueをセットし、市のドロップダウンリストは、選択された県の市名一覧をセットする。(県のプロパティに""がセットされた時は、市のドロップダウンリストを空にして選択不可とする。)
4.市のプロパティをセットされた時は、市のドロップダウンリストのSelectedValueをセットする。
でもこの方法はとらなくなりそう。
で、これの親のドロップダウンリストに対するプロパティsetの反映をどうするかで問題になりました。
ASP.NET2.0の動きだと、以下の順番に処理が動きます。
1.aspxページのPage_Load()
2.ascxユーザコントロールのPage_Load()
3.ボタンイベント処理。
DBから読み込み県のドロップダウンリストに県名一覧をセットする処理を、2でにやらせるとなると、非ポストバックのページ読み込み時(aspxのPage_Load())で、県のプロパティセットをしたときには、県のドロップダウンリストがまだできていない状態なので、ドロップダウンのSelectedValueにセットするというのは何かおかしな感じがする。
でも、2.の時点で、県のプロパティの値を見てSelectedValueをセットした場合は、1の処理でプロパティセットをした場合はうまくいくけど、3のボタンイベント処理で、プロパティセットした値は、ドロップダウンリストに反映されなくなる。
で、本当は、1.の前に動くであろう、ユーザコントロール内のドロップダウンリストのInitイベントで、IsPostBackがfalseのときだけ県名のドロップダウンリストに値を詰め込んでおけば、プロパティセット時には、ドロップダウンリストが出来上がっているのでプロパティセット時にドロップダウンリストのSelectedValueに値を詰め込めばよかっただけのような気がします。
つまり、
1.県のドロップダウンリストのInitイベントにてIsPostBackがfalseのときのみ県名一覧をセットする。
2.市のドロップダウンリストのInitイベントでは、選択不可とする。
3.県のプロパティがセットされた場合は、県のドロップダウンリストのSelectedValueをセットし、市のドロップダウンリストは、選択された県の市名一覧をセットする。(県のプロパティに""がセットされた時は、市のドロップダウンリストを空にして選択不可とする。)
4.市のプロパティをセットされた時は、市のドロップダウンリストのSelectedValueをセットする。
でもこの方法はとらなくなりそう。
2009年6月2日火曜日
複数の一行入力テキストボックスと直後のボタン
asp.netの話。
ページに複数の一行入力のテキストボックスとボタンを2つ配置すると。。
テキストボックスの入力中にEnterキーを押すと、テキストボックスの後で一番近い場所に配置したボタンクリックイベント処理が動く。
テキストボックスが1つだけだったときは、page_load処理だけが動くのに、テキストボックスが2つ以上あるとpage_load()とbutton_click()が動いてしまう。
。。。何かの嫌がらせなのだろうか?
ページに複数の一行入力のテキストボックスとボタンを2つ配置すると。。
テキストボックスの入力中にEnterキーを押すと、テキストボックスの後で一番近い場所に配置したボタンクリックイベント処理が動く。
テキストボックスが1つだけだったときは、page_load処理だけが動くのに、テキストボックスが2つ以上あるとpage_load()とbutton_click()が動いてしまう。
。。。何かの嫌がらせなのだろうか?
2009年5月30日土曜日
asp.net更新ボタン無効化
昨日の続き。昨日はhiddenfieldを使った、なんでもpostback制御だったんだけど、あのやり方だと、更新ボタンを押されたときに破綻しそう。なので、それだけを回避する措置を。
こんな感じの実装にしてみた。
やっていることは、セッション(サーバ側)とビューステート(HiddenField制御のようなクライアント側)と両方で同一タイムスタンプを持たせ、ポストバック時に、これが前回の情報と同じことを確認することで更新ボタンを押されたかどうかをチェックしているということです。
更新ボタンを押すということは、前回の送信情報と同じ情報をサーバ側に渡すことです。なので更新ボタンを押したときにサーバに渡す(クライアント側からのビューステートの)タイムスタンプがセッションで保持している情報と食い違うので、上のプログラムではボタン表示名が「不正」となります。なお、サーバとのやり取りが発生するタイミングでタイムスタンプを最新化しているので、サーバに送るデータで、サーバで一回も処理していないものに限り、ボタン名が正常となります。
こんな感じの実装にしてみた。
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
DateTime dt = System.DateTime.Now;
Session["TimeStamp"] = dt;
ViewState["TimeStamp"] = dt;
}
if (IsPostBack)
{
DateTime dt1 = (DateTime)Session["TimeStamp"];
DateTime dt2 = (DateTime)ViewState["TimeStamp"];
if (dt1 != dt2)
{
Button1.Text = "不正";
}
else
{
Button1.Text = "正常";
}
DateTime dt = System.DateTime.Now;
Session["TimeStamp"] = dt;
ViewState["TimeStamp"] = dt;
}
}
やっていることは、セッション(サーバ側)とビューステート(HiddenField制御のようなクライアント側)と両方で同一タイムスタンプを持たせ、ポストバック時に、これが前回の情報と同じことを確認することで更新ボタンを押されたかどうかをチェックしているということです。
更新ボタンを押すということは、前回の送信情報と同じ情報をサーバ側に渡すことです。なので更新ボタンを押したときにサーバに渡す(クライアント側からのビューステートの)タイムスタンプがセッションで保持している情報と食い違うので、上のプログラムではボタン表示名が「不正」となります。なお、サーバとのやり取りが発生するタイミングでタイムスタンプを最新化しているので、サーバに送るデータで、サーバで一回も処理していないものに限り、ボタン名が正常となります。
2009年5月29日金曜日
asp.netスパゲッティー
なんか無茶苦茶な感じがする。
asp.netの開発では、ボタン押下イベントは、処理が終わってからブラウザ側に制御が戻るんだけど、今回のはちょっと特殊な動きをしなければならない。
更新ボタンイベント→DBチェック→処理続行要否確認ダイアログ(はい/いいえ)→「はい」の場合にDB更新
という処理があって、これの実現方法が思いつかなかった。
で、プログラマに確認してみたところ、以下のようにやるとのこと。
1.ボタンイベントの処理では、DBチェックとダイアログ表示までを実施。
2.ダイアログにOKを押した場合、HIDDENタグに状態を記入してsubmitを行う。
3.ページロードのポストバック時の処理で、HIDDENタグの状態によって処理を変更。
というわけで、お化けのような馬鹿でっかいhiddenタグのif文だらけのPage_Load()になりそうだし、[F5]キーインによる、前回のデータ再送信なんかやられた日にはえらいことになる。なんでこんな仕様を許しちゃってるんだろう。
ちなみにプログラムはこんな感じ。
asp.netの開発では、ボタン押下イベントは、処理が終わってからブラウザ側に制御が戻るんだけど、今回のはちょっと特殊な動きをしなければならない。
更新ボタンイベント→DBチェック→処理続行要否確認ダイアログ(はい/いいえ)→「はい」の場合にDB更新
という処理があって、これの実現方法が思いつかなかった。
で、プログラマに確認してみたところ、以下のようにやるとのこと。
1.ボタンイベントの処理では、DBチェックとダイアログ表示までを実施。
2.ダイアログにOKを押した場合、HIDDENタグに状態を記入してsubmitを行う。
3.ページロードのポストバック時の処理で、HIDDENタグの状態によって処理を変更。
というわけで、お化けのような馬鹿でっかいhiddenタグのif文だらけのPage_Load()になりそうだし、[F5]キーインによる、前回のデータ再送信なんかやられた日にはえらいことになる。なんでこんな仕様を許しちゃってるんだろう。
ちなみにプログラムはこんな感じ。
protected void Button2_Click(object sender, EventArgs e)
{
string scr="<script language='javascript'>window.onload = function() { if (window.confirm('メッセージ')) { document.getElementById('HiddenField1').value='1';form1.submit(); } }</script>";
Page.ClientScript.RegisterClientScriptBlock(GetType(), "startup", scr);
}
で、Page_Loadではこんな感じ。
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
if (HiddenField1.Value == "1")
{
HiddenField1.Value = "0";
//DB更新
}
}
}
でもそういやぁ、
...showModalDialog();
location.href=location.href;
というプログラムがあったっけ、これは、ModalDialog処理後に、自ページを再読み込みさせたかったんだけど、hrefを使った画面遷移は、非ポストバック処理だし、ViewStateや当画面で入力した内容が消えてしまいそう。上のプログラムのようなsubmit()処理に変更せねば。。。
2009年5月28日木曜日
画面イメージキャプチャとソース行カウンタ
前は、キャプラとコロ助を使っていたけど、今はcaptstとbluestepcounterを使っています。
なんか、前よりもちょっといい感じがします。
遥か以前はキャプチャ&並べて印刷にWinShot+linarを使っていたなぁ。
ま、ツールはチーム内標準に合わせるだけなので特に思い入れはないですが。。。
なんか、前よりもちょっといい感じがします。
遥か以前はキャプチャ&並べて印刷にWinShot+linarを使っていたなぁ。
ま、ツールはチーム内標準に合わせるだけなので特に思い入れはないですが。。。
2009年5月27日水曜日
Visual Studio のクエリビルダやDataTable構成ウィザードって
Visual StudioでDataSetを作って、データアダプタで、こんなSQLを作ってみたんです。
SELECT TaskId, Name
FROM Task
WHERE (TaskId = (CASE WHEN @A = '1' THEN 10 END))
@Aというパラメータを渡すパラメータクエリ。
でも、クエリビルダでは、変数の型がおかしいといわれ、アダプタ作成完了時には、@Aを宣言してください。という警告メッセージが。'1'と比較しているんだから@Aは文字列型だって認識してくれないものなのだろうか?一応以下のようなどうでもよいものを付けるとテーブルアダプタの[構成]を押してSQLを作り直してもエラーにならないけど、ダミーを入れるとわけがわからなくなる。
WITH [DUMMY] AS (SELECT 1 AS Expr1
WHERE (@A = 'AAA'))
SELECT TaskId, Name
FROM Task
WHERE (TaskId = (CASE WHEN @A = '1' THEN 10 END))
どうしたものかなぁ?
SELECT TaskId, Name
FROM Task
WHERE (TaskId = (CASE WHEN @A = '1' THEN 10 END))
@Aというパラメータを渡すパラメータクエリ。
でも、クエリビルダでは、変数の型がおかしいといわれ、アダプタ作成完了時には、@Aを宣言してください。という警告メッセージが。'1'と比較しているんだから@Aは文字列型だって認識してくれないものなのだろうか?一応以下のようなどうでもよいものを付けるとテーブルアダプタの[構成]を押してSQLを作り直してもエラーにならないけど、ダミーを入れるとわけがわからなくなる。
WITH [DUMMY] AS (SELECT 1 AS Expr1
WHERE (@A = 'AAA'))
SELECT TaskId, Name
FROM Task
WHERE (TaskId = (CASE WHEN @A = '1' THEN 10 END))
どうしたものかなぁ?
登録:
投稿 (Atom)