連載:実践で役立つ業務アプリ開発のヒント

第2回 ユーザー・インターフェイス開発は分割して小さくする

えムナウ(児玉宏之)
Microsoft MVP Visual Developer - Visual C# JAN 2005 − DEC 2007)
2007/07/06
Page1 Page2 Page3

 前回はデータベース処理関連の実践的な開発手法について説明した。今回は、ユーザー・インターフェイス回りを効率的に開発する手法を紹介する。なお、使用するデータについては前回と同じものである。

2. コントロールや画面パーツの部品化のすすめ

「すべての画面で、現在、フォーカスがある場所が分かりにくい。一目で分かるように、フォーカスのあるコントロールの背景色を(黄色などに)変更してほしい」

「[Tab]キーだけでなく、[Enter]キーでも次のコントロールにフォーカスが移るようにしてほしい」

 このようなアプリケーション全体の仕様にかかわる変更を依頼されたことはないだろうか? そんなときに便利なのが、コントロールをラップする(=包む)手法である。

 画面のコントロールをあらかじめラッパー(以下、ラッパー・コントロール)として作っておけば、各画面に配置されたコントロールを1つ1つ修正しなくても、そのラッパー・コントロールを変更するだけで全画面に反映できる。さっそくこのようなラッパー・コントロールを作成して、前回のサンプル・プログラムに組み込んでみよう。

開発ヒント4:ラッパー・コントロールの作成

 具体的には、ラッパー・コントロールとは、既存のコントロール(のクラス)を継承して作成したコントロールのことだ。継承により、元のコントロールの機能はそのままに、新しい機能や特徴を追加した独自のコントロールを作ることができる。このようなコントロールをVisual Studio 2005で作成する手順を以下で説明しよう。

 ラッパー・コントロールを作成するにはまず、[ソリューション エクスプローラ]でプロジェクト項目を右クリックして[追加]−[新しい項目]を選ぶ。すると次のような[新しい項目の追加]ダイアログが表示される。

[新しい項目の追加]ダイアログ
「カスタム コントロール」テンプレートを選択して、新規コントロールを作成する。

 このダイアログで「カスタム コントロール」テンプレートを選択し、[ファイル名]にはラッパーとして分かりやすい名前を入力する(例えばテキストボックスのラッパーなら「BaseTextBox.vb」。この場合、作成されるコントロールはBaseTextBoxクラスとなる)。最後に[追加]ボタンをクリックする。

 次に、メニュー・バーから[プロジェクト]−[すべてのファイルを表示]を選択して、[ソリューション エクスプローラ]ですべてのファイルを表示する。[ソリューション エクスプローラ]では、いま追加したコードビハインド・ファイルとして「BaseTextBox.Designer.vb」というファイルが現れるはずだ。それを開き、

Inherits System.Windows.Forms.Control

というコード部分を、

Inherits System.Windows.Forms.TextBox

に書き直してビルドしよう。これによりカスタム・コントロールであるBaseTextBoxクラスがTextBoxクラスの派生クラスとなる。

 ここでWindowsフォーム・デザイナを開くと、次の画面のように、いま作成したBaseTextBoxコントロールがプロジェクトの名前の付いたツールボックスに現れ、Windowsフォームで利用できるようになる。なお、「BaseTextBox.vb」ファイルにはOnPaintイベント・ハンドラが自動的に追加されるが、不要なので削除して構わない。

ツールボックスに現れたBaseTextBoxコントロール

ラッパー・コントロールを活用したフォーカス時の背景色設定

 本稿の冒頭で「一目で分かるように、フォーカスのあるコントロールの背景色を(黄色などに)変更してほしい」という要望について記述したが、ここで先ほど作成したラッパー・コントロールであるBaseTextBoxコントロールを使ってこの要望を実現する例を示そう。

 まず先ほど作成したBaseTextBoxクラスのコード内容を以下のように書き換える。このコードは単に、フォーカスを受け取ったら背景色を明るい黄色(LightYellow)に変更し、フォーカスを失ったらデフォルトのコントロールの背景色に戻す処理を実装しているだけだ。

Public Class BaseTextBox

  ReadOnly DefaultFocusedBackColor As Color = Color.LightYellow

  Public Sub New
()
    InitializeComponent()

    _focusedBackColor = DefaultFocusedBackColor
    _unfocusedBackColor = Me.BackColor
  End Sub

  Private _focusedBackColor As Color
  Private _unfocusedBackColor As Color
  <System.ComponentModel.Category("Appearance"), System.ComponentModel.Description("フォーカスがあるときの背景色です")> _
  Public Property FocusedBackColor() As Color
    Get
      Return _focusedBackColor
    End Get
    Set(ByVal value As Color)
      _focusedBackColor = value
    End Set
  End Property

  ' フォーカスを受け取ったときの処理
  Private Sub BaseTextBox_Enter(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Enter
    _unfocusedBackColor = Me.BackColor
    Me.BackColor = FocusedBackColor
  End Sub

  ' フォーカスを失ったときの処理
  Private Sub BaseTextBox_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Leave
    Me.BackColor = _unfocusedBackColor
  End Sub

End Class
フォーカスのあり/なしで背景色を変更するラッパー・コントロールのコード

 以上で背景色を変更するラッパー・コントロール(BaseTextBoxコントロール)自体は完成だ。あとは、プロジェクトを新規にスタートした場合には、これをTextBoxコントロールの代わりに使えばよい。また前述のように顧客の要望で変更になった場合は、既存のTextBoxコントロールをBaseTextBoxコントロールに置き換えればよい。

ラッパー・コントロールを活用した都道府県ComboBox

 もう1つ例を示そう。この例では前回のサンプル・プログラムの中でラッパー・コントロールを活用してみる。

 いろいろな画面で共通に使うパーツを、ユーザー・コントロールにしてまとめている方は多いだろう。ユーザー・コントロールとは、複数のコントロールを組み合わせて作成したコントロールのことである。

 では、例えば都道府県を選択させるコンボボックス(以下、都道府県ComboBox)についてはどうだろうか? 手軽に作成できるからと、前回で示した手順(=コンボボックスやそれに対応する都道府県DataSetと都道府県TableAdapterを画面に配置・設定)を必要になるたびに繰り返してはいないだろうか? この繰り返しは共通処理としてまとめられるはずだ。

 このようなときにラッパー・コントロールを活用したい。以下では都道府県ComboBoxを実装する基になるラッパー・コントロール(BaseComboBoxコントロール)を作成してみる(その後、都道府県ComboBoxはそのBaseComboBoxコントロールを継承して作成する)。

 まず、ComboBoxコントロールのラッパー・コントロールとして「BaseComboBoxコントロール」を作成する。これには、カスタム・コントロールとしてBaseComboBox.vbファイルを新規に作成して、(BaseComboBox.Designer.vbファイルの)「Inherits System.Windows.Forms.Control」というコード部分を「Inherits System.Windows.Forms.ComboBox」に書き直す。

 そしてラッパー・コントロールで都道府県データを表示できるように、都道府県DataSetや都道府県TableAdapterも用意しておく。これらのデータセットとテーブルアダプタの作成方法は前回の記事を参考に作成してほしい。作成が少しでも楽になるように、都道府県テーブル用のストアド・プロシージャを作成するSQLスクリプトを用意した。以下のリンクからダウンロードできる(なお、このSQLスクリプトは、SQL Serverのクエリ・アナライザやMicrosoft SQL Server Management Studio Expressから実行できる)。

 次に先ほど作成したBaseComboBoxコントロールを継承して都道府県ComboBoxを作成する。これもラッパー・コントロールの作成方法と同じ手順で、カスタム・コントロール(=拡張コントロール)として都道府県ComboBox.vbファイルを新規に作成して、(都道府県ComboBox.Designer.vbファイルの)「Inherits System.Windows.Forms.Control」というコード の部分を、「Inherits BaseComboBox」に書き直せばよい。

 都道府県データはエンド・ユーザーが値を入力するよりもリストから選択できる方が便利なので、(都道府県ComboBox.vbファイルを開いて[プロパティ]ウィンドウで)DropDownStyleプロパティを「DropDownList」に設定しておくとよい。都道府県データは今後変更されるとはあまり考えられず、そもそもデータ量も多くないので、一度読み込んだらほかの画面でも使い回す方が効率がよい。また、Windowsフォームでのデザイン時にはデータベースから都道府県データを読み込まないようにしておけば、データベースが接続されていない環境でも画面作成ができるようになる。

 以上の観点を考慮して都道府県ComboBoxを実装したのが次のコードである。

Public Class 都道府県ComboBox
    Implements System.ComponentModel.ISupportInitialize

  Public Sub New()
    InitializeComponent()

    ' 都道府県データは1度だけ読み込む
    If 都道府県ComboBox.SavedDataSet Is Nothing Then
      InitializeDataSet()
    End If
    Me.DataSource = 都道府県ComboBox.SavedDataSet
    Me.ValueMember = "都道府県.コード"
    Me.DisplayMember = "都道府県.都道府県名"
  End Sub

  Shared SavedDataSet As 都道府県DataSet
  Shared SavedTableAdapter As 都道府県DataSetTableAdapters.都道府県TableAdapter

  Protected Sub InitializeDataSet()
    都道府県ComboBox.SavedDataSet = New 都道府県DataSet
    都道府県ComboBox.SavedTableAdapter = New 都道府県DataSetTableAdapters.都道府県TableAdapter
    CType(都道府県ComboBox.SavedDataSet, System.ComponentModel.ISupportInitialize).BeginInit()
    都道府県ComboBox.SavedDataSet.DataSetName = "都道府県DataSet"
    都道府県ComboBox.SavedDataSet.SchemaSerializationMode = System.Data.SchemaSerializationMode.IncludeSchema
    CType(都道府県ComboBox.SavedDataSet, System.ComponentModel.ISupportInitialize).EndInit()
    都道府県ComboBox.SavedTableAdapter.ClearBeforeFill = True
  End Sub

  Private Sub BeginInit() Implements System.ComponentModel.ISupportInitialize.BeginInit

  End Sub

  Private Sub EndInit() Implements System.ComponentModel.ISupportInitialize.EndInit
    ' Windowsフォーム・デザイン時は都道府県データを読み込まない
    If Not Me.DesignMode Then
      If 都道府県ComboBox.SavedDataSet.都道府県.Count = 0 Then
        SavedTableAdapter.Fill(都道府県ComboBox.SavedDataSet.都道府県)
      End If
    End If
  End Sub
End Class
ラッパー・コントロールとして実装した都道府県ComboBoxのコード(都道府県ComboBox.vb)

 以上で都道府県ComboBoxの実装は完了である。あとは、この都道府県ComboBoxを既存のコンボボックスの代わりに利用するだけだ。

 ここまでに説明したのが、複数のコントロールに共通する要素を1つの部品にまとめて、それぞれのコントロールではそれを基底クラスとして利用することで、実装の効率化と簡素化を実現するテクニックである。これはコントロール・レベルのテクニックだが、続いて、さらに粒度を大きくして、複数のコントロールを含む画面パーツ(=1つの画面を構成する部品)のレベルで1つの部品にまとめるテクニックを紹介しよう。


 INDEX
  実践で役立つ業務アプリ開発のヒント
  第2回 ユーザー・インターフェイス開発は分割して小さくする
  1.開発ヒント4:ラッパー・コントロールの作成
    2.開発ヒント5:画面パーツのユーザー・コントロール化
    3.開発ヒント6:BindingSourceコンポーネントは共通で使う
 
インデックス・ページヘ  「実践で役立つ業務アプリ開発のヒント」


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メールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)
- PR -

注目のテーマ

業務アプリInsider 記事ランキング

本日 月間
ソリューションFLASH