.NET TIPS

[ASP.NET]Webフォーム上のフォーカスを制御するには?[2.0、3.0、3.5、C#、VB]

山田 祥寛
2008/04/24

 ASP.NETページを構築する場合、フォーカスを制御したいというケースは少なくない。例えば、入力フォームではページ・ロード時に最初の入力要素に自動でフォーカスをセットしておけば、利用者はいちいちマウスでフォーカスを合わせる手間が省けるため便利だ。ささいなことではあるが、特に同一のフォームで連続して入力するようなケースでは、入力効率を大幅に向上できるだろう。また、入力項目にエラーがあった場合には単にエラー・メッセージを出力するだけでなく、エラー項目に自動でフォーカスが移動すれば、エラー個所を探す手間を省くことができるだろう。

 これらはフォーカス操作の一例にすぎないが、こうしたちょっとした気配りがユーザビリティを底上げすることがお分かりいただけるのではないか。そして、ASP.NET 1.1以前でこのようなフォーカスの制御を行うには、JavaScriptのコードを直接に記述する必要があった(方法については、「TIPS:[ASP.NET]コントロールにフォーカスをセットするには?」を参照されたい)。コード自体はごく定型的なものであるが、定型的であるからこそ、そのような操作のためにいちいち煩雑なコードを記述したくない、というのが人情というものだろう。

 そこでASP.NET 2.0以降ではクライアントサイド・スクリプトとの連携が強化され、ページ上の要素に対するフォーカスの制御も、サーバサイドのコードから自由に制御できるようになっている。本稿では、ASP.NET 2.0以降で利用可能な、いわゆる「Focus API」について解説する。

 なお、本稿では動作確認のためのサンプル・ページとして、以下のようなFocus.aspxを用意しておくものとする。

Focus.aspxのフォーム・レイアウト
フォーム上には以下のコントロールを配置する。
コントロール(ID) プロパティ 設定値
TextBox(txtName)
Button(btnSend) Text 送信
RequiredFieldValidator(reqName) ControlToValidate txtName
ErrorMessage 名前が入力されていません。
Label(lblResult) Text 初期状態です。

protected void btnSend_Click(Object sender, System.EventArgs e) {
  lblResult.Text = "btnSendがクリックされました。";
}
Protected Sub btnSend_Click(ByVal sender As Object, ByVal e As System.EventArgs)
  lblResult.Text = "btnSendがクリックされました。"
End Sub
[送信]ボタンをクリックしたときのコード(Focus.aspx)(上:C#、下:VB)

●デフォルト・フォーカスを設定する

 それでは、まずはページ・ロード時にデフォルトでフォーカスを設定する方法を見てみよう。ページ・ロード時にテキストボックスtxtNameにフォーカスをセットするには、Focus.aspxに対して、コード・エディタから以下のような記述を追加するだけだ。

<form id="form1" runat="server" DefaultFocus="txtName">
デフォルト・フォーカスを設定するコード(Focus.aspx)

 DefaultFocus属性には、フォーカスを置きたいコントロールのID値をセットする。果たして、実行してみると、初期状態でテキストボックスにフォーカスがセットされているのが確認できるはずだ。次の画面は、このコードを実行したもの。

初期状態でテキストボックスにフォーカスがセットされた

 ちなみに、ここでは静的にデフォルト・フォーカスを設定しているが、次のようにコードから動的にデフォルト・フォーカスを設定することも可能である。

protected void Page_Load(Object sender, System.EventArgs e) {
  Page.SetFocus(txtName);
  // txtName.Focus(); // これでもOK
}
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
  Page.SetFocus(txtName)
  // txtName.Focus() ' これでもOK
End Sub
イベント・ハンドラからフォーカスを設定するコード(Focus.aspx)(上:C#、下:VB)

 フォーカスをセットするには、Page.SetFocusメソッド、または上のコードではコメントアウトしているが、個別のコントロールからFocusメソッドを呼び出せばよい(いずれも意味的には同じである)。先述したDefaultFocusプロパティが併せて設定されている場合も、SetFocus/Focusメソッドが呼び出された場合にはこちらの操作が優先される。

●デフォルト・ボタンを設定する

 デフォルト・ボタンとは、フォーム上で[Enter]キーを押下した場合に、(該当するボタンにフォーカスが当たっていなくても)デフォルトでクリックされたものと見なされるボタンのこと。フォームを入力する場合には、キーボードだけで操作をしていることも多いが、デフォルト・ボタンを設定しておくことでいちいち該当のボタンに[Tab]キーなどでフォーカスを移さなくても、フォームを入力し終わった時点で[Enter]キーを押すことでフォームを送信でき、操作性を向上できる。

 まずは、デフォルト・ボタンを設定しない場合の挙動を確認してみる。テキストボックス上にフォーカスが当たっている状態で[Enter]キーをクリックしてみよう。ページ下部の文字列は変わらず、ButtonコントロールbtnSendに関連付けられたClickイベント・ハンドラが実行されて「いない」ことが確認できる。

テキストボックス上で[Enter]キーを押下したとき(btnSend_Clickイベント・ハンドラが実行され「ない」)

 そこで次に、コード・エディタから<form>タグにDefaultButton属性を追加してみよう。

<form id="form1" runat="server" DefaultFocus="txtName"
  DefaultButton="btnSend">
デフォルト・ボタンを設定するコード(Focus.aspx)

 DefaultButton属性には、DefaultFocus属性と同様、デフォルト・ボタンとして設定したいコントロールのID値をセットする。

 この状態でもう一度、Focus.aspxを実行し、テキストボックス上にフォーカスが当たっている状態で[Enter]キーをクリックしてみよう。今度はページ下部の文字列が書き換えられ、確かにButtonコントロールbtnSendに関連付けられたClickイベント・ハンドラが実行されていることを確認できるはずだ。

テキストボックス上で[Enter]キーを押下したとき(btnSend_Clickイベント・ハンドラが実行される)

 なお、DefaultButton属性にボタン系コントロール以外のコントロールを指定した場合には、InvalidOperationException例外が発生するので、注意すること。

●検証エラー時にエラー項目にフォーカスをセットする

 今度は、検証コントロールで検証エラーが検出されたときに、エラー項目にフォーカスを移動させてみよう。これには、該当の検証コントロールに対してSetFocusOnErrorプロパティにTrueをセットするだけだ(デフォルトはFalse)。

 また、フォーカスが正しくセットされている様子を確認するために、もしもすでにDefaultFocus属性やSetFocus/Focusメソッドを記述している場合には、これらを削除しておこう。

 Focus.aspxを実行し、[名前]欄に何も入力しない状態で[送信]ボタンをクリックすると、以下の画面のように確かにエラー項目([名前]欄)にフォーカスがセットされていることを確認できる。

検証エラー時にエラー項目に自動的にフォーカスをセット

●非同期通信の後にフォーカスをセットする

 最後に、非同期ポストバックを行った後に、特定の要素にフォーカスをセットする方法だ(*)。

* 本サンプルはASP.NET AJAXの機能であるので、ASP.NET 2.0環境である場合には、あらかじめ「DBプログラミング 7つのヒント − 同時実行制御からASP.NET AJAXまで −」の内容に従って、ASP.NET AJAXをインストールしておく必要がある(ASP.NET 3.5環境では不要)。

 以下のようなページが用意されているものと想定しよう。

Focus2.aspxのフォーム・レイアウト
フォーム上には以下のコントロールを配置する。
コントロール(ID) プロパティ 設定値
ScriptManager(manager)
UpdatePanel(upanel)
TextBox(txtName)
Button(btnSend) Text 送信
<form> DefaultFocus txtName(*
* DefaultFocus属性は、コード・エディタから指定する必要がある。

 まずはこの状態でFocus.aspxを実行し、[送信]ボタンをクリックしてみよう。最初のページ起動時はテキストボックスにフォーカスがセットされるが、[送信]ボタンをクリックして非同期ポストバックを実行した後は、フォーカスが外れてしまうことが確認できるはずだ。これは、先述したPage.SetFocusメソッドを利用しても同様である。

非同期ポストバックの後にはテキストボックスにフォーカスがセットされない

 非同期ポストバックでフォーカスを制御するには、ScriptManager.SetFocusメソッドを使用する必要があるのである。

protected void Page_Load(Object sender, System.EventArgs e) {
  manager.SetFocus(txtName);
}
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
  manager.SetFocus(txtName)
End Sub
イベント・ハンドラからフォーカスを設定するコード(Focus2.aspx)(上:C#、下:VB)

 この状態でもう一度、Focus2.aspxを実行し、[送信]ボタンをクリックしよう。今度は非同期ポストバックの後もテキストボックスにフォーカスがセットされることを確認できる。End of Article

利用可能バージョン:.NET Framework 2.0
利用可能バージョン:.NET Framework 3.0
利用可能バージョン:.NET Framework 3.5
カテゴリ:Webフォーム 処理対象:クライアント・スクリプト
カテゴリ:Webフォーム 処理対象:ASP.NET AJAX
使用キーワード:DefaultFocus属性
使用キーワード:Page.SetFocusメソッド
使用キーワード:Focus API
関連TIPS:[ASP.NET]コントロールにフォーカスをセットするには?

この記事と関連性の高い別の.NET TIPS
[ASP.NET]コントロールにフォーカスをセットするには?
Windowsアプリのコントロールで[Tab]キーによるフォーカスを与えないようにするには?
Windowsフォームのロード時に任意のコントロールへフォーカスを設定するには?
[Silverlight 2]ページ表示時にテキストボックスにフォーカスを設定するには?
Windowsアプリケーションで[Enter]キーによるフォーカス移動を行うには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム Jigsaw(ジグソー) により自動抽出したものです。
generated by

「.NET TIPS」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間