CodeZine(コードジン)

特集ページ一覧

Visual Studio 2005のフォームにおけるBindingNavigatorの拡張

BindingNavigatorによるデータアクセスアプリケーションの開発効率アップ

  • ブックマーク
  • LINEで送る
  • このエントリーをはてなブックマークに追加
2006/06/26 00:00

本稿では、BindingNavigatorコンポーネントの機能を拡張するユーザーコントロールの作成方法を示します。BindingNavigatorコンポーネントは、ほんの少しの拡張を加えるだけで、ナビゲーション機能とデータアクセスに関するCRUD機能をほぼ自動的に実装することができます。

目次

はじめに

 Visual Studio 2005では、WindowsアプリケーションとSmart Clientアプリケーションを短期間で構築できるように、さまざまな点がすばらしく向上しています。[Data Sources]パネルを使えば、各種コントロールをフォームに配置し、それらをBindingSourceコンポーネントでバインドするという操作が自動で行えます。BindingNavigatorコンポーネントには非常に大きな可能性が隠されており、ほんの少しの拡張を加えるだけで、ナビゲーション機能とデータアクセスに関するCRUD(Create、Read、Update、Delete=作成、更新、取得、削除)機能をほぼ自動的に実装することができます。本稿では、BindingNavigatorコンポーネントの機能を拡張するユーザーコントロールの作成方法を示します。

 以前の記事では、Visual Studio 2005のRAD機能に焦点を当て、ビジネス層とデータアクセス層を自動生成することですばやくN階層のWindowsアプリケーションを作成する方法を説明しました。本稿では、以前の記事で取り上げた概念に基づいて、より迅速なアプリケーション開発を実現するコードテンプレートとユーザーコントロールのシンプルなアーキテクチャを紹介します。

 今回のアーキテクチャでは、ユーザーコントロール内のBindingNavigatorコンポーネントを拡張して、編集済みデータの保存機能を自動生成するようにしています。そのためには、Bining Sourceコントロールを拡張し、インターフェイステンプレートをデータアクセスロジックに追加する必要があります。

Visal Studio 2005のBindingNavigatorコンポーネント

 新しくVisual Studio 2005のRADツールに加わったこの機能を理解するために、実際に使ってみることにしましょう。新しいアプリケーションを作成し、Northwindデータベースの「Customer」テーブルと「Order」テーブルを使用して、新しいデータソース(DataSet)を追加します(詳しい手順は、筆者の前の記事を参照してください)。

 [Data Sources]パネルの[Typded Dataset]からテーブルやフィールドをドラッグしてフォームにドロップすると、すぐに使えるバインド済みのデータアクセスロジックが作成されます。先ほど作成した新しいデータソースの「Customer」テーブルをフォームにドラッグしてください。すると、ウィザードによってそのデータセットのインスタンスが作成され、さらに、そのデータセット内のテーブルにリンクされるBindingSourceコンポーネントと、このバインディングソースにリンクされるBindingNavigatorコンポーネントが作成されます。データセットがプロジェクトにとってローカルである場合は、さらにテーブルアダプタのインスタンス化が行われ、Fillメソッドの呼び出しが追加されます(ただし、オブジェクトデータソースを使っている場合は、このコードを手作業で追加する必要があります)。

 BindingNavigatorコンポーネントによって、ユーザーがレコード間をナビゲートするための一連のツールがフォームの最上部に配置されます。最初のレコード、前のレコード、次のレコード、最後のレコードに移動するためのボタンと、インデックス番号を指定して特定のレコードに直接移動するためのフィールドがあります。

 レコードの追加と削除、そして編集結果の保存を行うためのボタンも追加されます。保存用のボタン(フロッピーディスクのアイコン)は、標準的なナビゲーションバーの一部ではなく、データソースウィザードによって特別に追加されます。本稿を執筆するきっかけとなったのは、この保存ボタンです。

 データセットがプロジェクトにローカルである場合は、保存ボタンがナビゲーションバーに追加されるときに、適切なコードが生成されます(オブジェクトデータソースを使用する場合は、この限りではありません)。「Customer」テーブル用には、次のメソッドが追加されます。

Private Sub CustomersBindingNavigatorSaveItem_Click( _
    ByVal sender As System.Object, ByVal e As System.EventArgs) _
    Handles CustomersBindingNavigatorSaveItem.Click
    Me.Validate()
    Me.CustomersBindingSource.EndEdit()
    Me.CustomersTableAdapter.Update(Me.NorthwindDataSet.Customers)
End Sub

 Validateコマンドは、コントロールの編集を終わらせます。バインディングソースのEndEditメソッドは、コントロール内の編集済みデータをすべてデータセットのレコードに書き戻します。テーブルアダプタのUpdateコマンドは、更新済みレコードをデータベースに反映させます。

 この新しいコントロールは大幅な拡張であり、通常はこれで、データバウンドフォームに関するナビゲーションとCRUDのニーズの大部分を満たすことができます。しかし、データバウンドフォームのニーズすべてに対処する完全なツールを作るには、いくつか足りない点があります。克服しなければならない問題としては、次のようなものがあります。

  1. オブジェクトデータソースを使う場合は、データテーブルへのデータ読み込みおよびデータテーブルの更新を行うためのコードがウィザードによって自動生成されません。このコードは手作業で追加する必要があります。
  2. データを編集したときは、ユーザーが忘れずに保存ボタンをクリックしなければなりません。データが変更されても、IsDataDirtyフラグはセットされません、そのため、ユーザーがレコードを変更し、保存しないままでいても警告メッセージは表示されません。
  3. レコードを削除する場合も、警告または確認メッセージは表示されません。
  4. ナビゲーションバーには、特定レコードをルックアップする手段も必要です。

汎用的なテーブル更新インターフェイス

 1番目の問題に対処するには、データテーブルのデータ読み込み(Fill)と更新(Update)を実行する、汎用的なコードを作成する必要があります。筆者の以前の記事のパート3では、データアクセスロジックをビジネス層にラップしてしまうコードを紹介しました。その後、この構造に少し手を加え、データテーブルのサブクラスを利用してメソッドの一貫性を高めるように書き換えました。この一貫性を実現するには、個々のテーブルクラスがラッパー内で実装するインターフェイスを作成する必要があります。

  1. ソリューションエクスプローラでプロジェクトを右クリックし、[Add]-[New Item]を選択します(多層アプリケーションの場合は、これはビジネス層で行うべき処理ですが、話を簡単にするために、ここではまずWindowsプロジェクトに格納して、後から移動することにします)。
  2. [Choose a Class]を選び、「_Interface」と名前を付けます(先頭にアンダーバーを付けることで、ソート時にこのクラスが一番上に来るようにしています)。このクラスを、汎用的なメソッドを持ち、プログラム全体を通じてアクセスできるユーティリティ的なクラスにします。
  3. _Interfaceクラス内に、FillメソッドとUpdateメソッドを要求する「ITableUpdate」という名前のインターフェイスを作成します。
  4. Public Class _Interface
        ''' <summary>
        ''' Interface for Data table in a dataset
        '''  to standardize fill and update methods
        ''' </summary>
       Public Interface ITableUpdate
            Sub Fill()
            Sub Update()
        End Interface
    End Class
    

 データセットの背後にあるパーシャルクラス(データセットを右クリックして[View Code]をクリックすると表示されます)内で、データセット内の更新可能なテーブル1つ1つに対して次のテンプレートコードを作成します。この例では、「NorthwindDataSet」テーブルに関するCustomerクラスを実装しています。

Partial Class NorthwindDataSet
    Shared taCustomer As New _
        NorthwindDataSetTableAdapters.CustomersTableAdapter

    Partial Class CustomersDataTable
        Implements _Interface.ITableUpdate

        Public Sub Fill() Implements _Interface.ITableUpdate.Fill
        taCustomer.Fill(Me)
        End Sub

        Public Sub Update() Implements _Interface.ITableUpdate.Update
            taCustomer.Update(Me)
        End Sub
    End Class
End Class

 このインターフェイスを実装することにより、どのテーブルでも汎用的なUI呼び出しが使えるようになります。つまり、Saveメソッドは、「Customer」テーブル用の更新メソッドを呼び出す代わりに、汎用的なコードを使って更新を呼び出せるようになります。保存ルーチンを一度書いておけば、個々のテーブル用にいちいちコードを書き直さなくても、同じコードを再利用できるというわけです。


  • ブックマーク
  • LINEで送る
  • このエントリーをはてなブックマークに追加

あなたにオススメ

著者プロフィール

  • David Catherman(David Catherman)

    CMI Solutions所属。データベースアプリケーションのデザイン/開発に20年以上の経験を持ち、ここ4、5年は特にMicrosoft .NETとSQL Serverに仕事が集中している。現在はCMI Solutionsのアプリケーション設計者および上級開発者であり、Visual Studioと...

  • japan.internet.com(ジャパンインターネットコム)

    japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.com や EarthWeb.c...

バックナンバー

連載:japan.internet.com翻訳記事

もっと読む

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5