Visual Studio 2010でデータベース開発特集:Visual Studio 2010で社内C/Sシステム開発(後編)(2/4 ページ)

» 2011年01月05日 00時00分 公開
[一色政彦,デジタルアドバンテージ]

■[ユーザー登録]コンテンツ(詳細)の開発

 それでは各メニューのコンテンツ作成に入っていこう。取りあえずユーザーを登録できなければ何も始められない。そこで、[ユーザー登録]メニューのコンテンツから開発する。

コンテンツ作成の準備

 [ソリューション エクスプローラー]から[ユーザー登録]コンテンツ(=ContetUserEntry.xamlファイル。前回解説したように実体はユーザー・コントロール)をダブルクリックで開いて、前回、切り替え識別用に追加したTextBlockコントロールを削除しよう(=WPFデザイナ上の該当コントロールをクリックにより選択して[Delete]キーを押す)。

「詳細」コントロールの作成

 次に、何もなくなったユーザー・コントロールのGridパネル上に「詳細」(=項目名を示すLabelコントロール+入力欄となるTextBoxコントロールなどの組み合わせを1行として、入力項目の数だけ行が並べられたGridパネル)を追加する。

 この方法は「特集:初めてのWPF/Silverlightデータグリッド開発」で説明しているので、以下では重要なポイント以外の詳細な説明は割愛させていただく。

「詳細」コントロールの追加

 簡単に説明しておくと、作成したデータセットは(その階層構造がツリー形式で)[データ ソース]ウィンドウに表示されるので、データセット項目の直下にある「User」データテーブル項目の右端にある[▼]ボタンからWPFデータ・バインド・コントロールとして[詳細]を選択し、各列項目の右端にある[▼]ボタンからそれぞれ下記の表のとおりのコントロールを選択する。

列名 コントロール
ID [なし]
Name TextBox
DutyPerson CheckBox
Order [なし]
Userデータテーブルの各列に割り当てるコントロール
Order列は、OrderテーブルのUser_ID列(=外部キー)が、UserデータテーブルのID列(=親キー)を参照しているために表示されている。

 後は、その「User」データテーブル項目を、WPFデザイナのデザイン・サーフェイス上にドラッグ&ドロップする(次の画面を参照)。

WPFデザイナのデザイン・サーフェイス上に追加されたUserデータテーブルに対応する「詳細」(=Gridパネル)

 追加された「詳細」(=Gridパネル)の左上に表示されている[+]部分の右クリック・メニューから[レイアウトのリセット]−[すべて]を実行すると、「詳細」がユーザー・コントロール全体に広がる。

Gridパネルの既存行の前後への、行の追加

 この状態でコードを少し記述すれば、既存のUserデータを表示できる。しかし、ここで行いたいのは、(表示ではなく)むしろ「ユーザー登録」の処理だ。これを実現するために、Gridパネルにもう1行追加して、その行に[登録]ボタンを配置することにしよう。

 前回はグリッド線を引く方法を説明したが、今回は既存行の前後に行を追加する方法を説明しよう。

 ここでは[Duty Person]チェックボックス行の下に1行追加する。これには、WPFデザイナでそのチェックボックスを右クリックし、表示されるコンテキスト・メニューから[グリッド行]−[後ろへ挿入]を実行すればよい(当然、上に1行追加する場合は、[前へ挿入]を実行)。

既存行の下に新たな行を追加していることころ

 追加された行の2列目に[ツールボックス]からButtonコントロール(名前:ButtonAdd、Contentプロパティ:登録)をドラッグ&ドロップしよう。

 Girdパネルの目的のセルにコントロールを適切に追加するには、少しコツが必要だ(これについて「前編:【コラム】Gridパネルのセルにコントロールを追加する方法」を参照してほしい。なお、このコラムは前編公開後の2010年12月21日に追記したもの)。

 ドラッグ&ドロップした結果は次のとおり。

Gridパネルの1つのセルにButtonコントロールを配置したところ

 そのほか、Gridパネル自体のMarginプロパティの設定や、Gridパネルの列や行のサイズなど、見た目に関する微調整が必要だ。また、「詳細」で追加された各行のLabelコントロールのContentプロパティに適切な項目名を設定する必要がある。これらの調整作業は、今回の本旨からは外れる内容なので割愛する(これらの作業については、前編が参考になるだろう)。

新規データ行の追加処理(=データテーブルによるDBアクセス)

 次に、[登録]ボタンがクリックされた際に、Userテーブルに新しいユーザー(=新規行)を登録する処理を実装しよう。

 WPFデザイナ上の[登録]ボタンをダブルクリックして、Clickイベント・ハンドラを追加すると、XAMLファイルのコードビハインドであるContetUserEntry.xaml.cs/.vbファイルが自動的に開かれる。このファイルには、(次の画面からも分かるように)UserControl_LoadedメソッドとButtonAdd_Clickメソッドが生成されている。UserControl_Loadedメソッド内はコメント・アウトされているが、先ほどの「詳細」を追加したときに自動生成されたものだ。

XAMLファイルのコードビハインド・ファイルに自動生成されたメソッド群(C#)
VBの場合も同様の内容が自動生成される。

 このコードを次のように書き換える。

using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using ObentoApp.ObentoDataSetTableAdapters;

……省略……

private ObentoDataSet        myDS;  // データセット
private UserTableAdapter     myTA;  // Userテーブルアダプタ
private CollectionViewSource myCVS; // コレクションビューソース

private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
  // デザイン時にはデータは読み込まれません
  if (!DesignerProperties.GetIsInDesignMode(this))
  {
    // XAMLファイル側で作成されたデータセットを取得
    myDS = ((ObentoDataSet)(this.FindResource("obentoDataSet")));

    // Userテーブルアダプタで、データセットにUserデータを読み込む
    myTA = new UserTableAdapter();
    try
    {
      myTA.Fill(myDS.User);
    }
    catch (Exception ex)
    {
      MessageBox.Show("ユーザー・データの読み込みでエラーが発生しました。\n" + ex.Message);
      return;
    }

    // XAMLファイル側で作成されたコレクションビューソースを取得
    myCVS = (CollectionViewSource)this.Resources["userViewSource"];
    // コレクションビューソース内の新規行に移動
    myCVS.View.MoveCurrentTo(null);
  }

}

private void ButtonAdd_Click(object sender, RoutedEventArgs e)
{
  // ユーザー名を取得
  string name = nameTextBox.Text.Trim();
  if (String.IsNullOrEmpty(name))
  {
    MessageBox.Show("ユーザー名を入力してください。");
    return;
  }
  // お弁当当番かどうかを取得(Nullable型の判定で??演算子を使用)
  bool dutyPerson = dutyPersonCheckBox.IsChecked ?? false;

  // データセット内のUserデータテーブルに新規行を追加
  myDS.User.AddUserRow(name, dutyPerson);
  // Userテーブルアダプタで、Userデータをデータベースに書き込む
  try
  {
    myTA.Update(myDS.User);
  }
  catch (DBConcurrencyException de)
  {
    MessageBox.Show("登録に失敗しました。\n" + de.Message);
    return;
  }
  catch (Exception ex)
  {
    MessageBox.Show("エラーが発生しました。\n" + ex.Message);
    return;
  }

  // コレクションビューを更新
  myCVS.View.Refresh();
  // コレクションビューソース内の新規行に移動
  myCVS.View.MoveCurrentTo(null);
}

……省略……

Imports System.ComponentModel
Imports ObentoApp.ObentoDataSetTableAdapters

……省略……

Private myDS As ObentoDataSet         // データセット
Private myTA As UserTableAdapter      // Userテーブルアダプタ
Private myCVS As CollectionViewSource // コレクションビューソース

Private Sub UserControl_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded

  // デザイン時にはデータは読み込まれません。
  If Not (DesignerProperties.GetIsInDesignMode(Me)) Then

    // XAMLファイル側で作成されたデータセットを取得
    myDS = CType(Me.FindResource("ObentoDataSet"), ObentoDataSet)

    // Userテーブルアダプタを生成
    myTA = New UserTableAdapter()
    // Userテーブルアダプタで、データセットにUserデータを読み込む
    Try
      myTA.Fill(myDS.User)
    Catch ex As Exception
      MessageBox.Show("ユーザー・データの読み込みでエラーが発生しました。" & vbLf & ex.Message)
      Return
    End Try

    // XAMLファイル側で作成されたコレクションビューソースを取得
    myCVS = CType(Me.Resources("UserViewSource"), CollectionViewSource)
    // コレクションビューソース内の新規行に移動
    myCVS.View.MoveCurrentTo(Nothing)

  End If

End Sub

Private Sub ButtonAdd_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles ButtonAdd.Click

  // ユーザー名を取得
  Dim name As String = NameTextBox.Text.Trim()
  If String.IsNullOrEmpty(name) Then
    MessageBox.Show("ユーザー名を入力してください。")
    Return
  End If
  // お弁当当番かどうかを取得(Nullable型の判定でIf演算子を使用)
  Dim dutyPerson As Boolean = If(DutyPersonCheckBox.IsChecked, False)

  // データセット内のUserデータテーブルに新規行を追加
  myDS.User.AddUserRow(name, dutyPerson)
  '  Userテーブルアダプタで、Userデータをデータベースに書き込む
  Try
    myTA.Update(myDS.User)
  Catch de As DBConcurrencyException
    MessageBox.Show("登録に失敗しました。" & vbLf & de.Message)
    Return
  Catch ex As Exception
    MessageBox.Show("エラーが発生しました。" & vbLf & ex.Message)
    Return
  End Try

  // コレクションビューを更新
  myCVS.View.Refresh()
  // コレクションビューソース内の新規行に移動
  myCVS.View.MoveCurrentTo(Nothing)
End Sub

……省略……

新規行を追加するコード例(上:ContetUserEntry.xaml.cs、下:ContetUserEntry.xaml.vb)
FindResourceメソッドやResourcesプロパティに指定しているリソース・キー名が、C#の場合は頭文字が小文字、VBの場合は頭文字が大文字になっているので注意してほしい。これは、(基本的に)VS 2010による自動生成がそのような出力になっているため。

 この状態でビルドしてアプリケーションを実行すると、ユーザーを登録できる。

 次に、「詳細」で既存データを移動できるようにする(これにより既存データを修正/削除できるようになる)。また、各種リソースをアプリケーション全体で共有する。

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。