はじめに
前回は、
しかし、
そこで今回はDataSetやComponentという方法を用いて、
DataSetとは?
DataSetは、
Componentとは?
再利用性の高いオブジェクトを部品化したもの、
例えば、
作成するにあたっての注意
今回、
そこで、
DataSetの作成
新規作成
DataSetを新規作成する手順は次の通りです。

最初に、

「新しい項目の追加」
サーバーエクスプローラーにデータベースを接続
DataSetを編集してテーブルを追加します。

DataSetの編集画面に表示されているメッセージの

データ接続を選択後に右クリックしてメニューを表示します。
ここから

「接続の追加」
データテーブルを編集
DataSetにデータテーブルをマッピングします。

サーバーエクスプローラーの画面からMyTableをドラッグして、

これによって、
この状態で、
Logicの作成
次にLogicコンポーネントを作成します。
新規作成
ソリューションエクスプローラーから、

上記のように、
BindingSource1の設定
BindingSourceは、

上記のように、
BindingSourceオブジェクトとユーザーコントロールのバインディングの方法は、
コードの作成
Logic クラスのコードは次のようになります。
なお、
using System;
using System.Data;
using System.ComponentModel;
namespace WindowsFormsApplication1
{
//*************************************************************
/// <summary>電話帳サンプル</summary>
//*************************************************************
public partial class Logic :
Component, INotifyPropertyChanged
{
//*************************************************************
/// <summary>コンストラクタ</summary>
//*************************************************************
public Logic() {
this.InitializeComponent();
}
public Logic(IContainer container) {
if (container != null) container.Add(this);
this.InitializeComponent();
}
//*************************************************************
/// <summary>PropertyChanged イベント</summary>
//*************************************************************
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName) {
if (this.PropertyChanged == null) return;
this.PropertyChanged(
this, new PropertyChangedEventArgs(propertyName));
}
//*************************************************************
/// <summary>Code プロパティ</summary>
//*************************************************************
private int _Code;
public int Code {
get { return this._Code; }
set {
if (this._Code == value) return;
this._Code = value;
this.OnPropertyChanged("Code");
}
}
//*************************************************************
///<summary>BindingSource プロパティ</summary>
//*************************************************************
public System.Windows.Forms.BindingSource BindingSource {
get { return this.bindingSource1; }
}
//*************************************************************
/// <summary>DataSet オブジェクトにテーブルデータを格納します
/// </summary>
//*************************************************************
public void Fill() {
this.myTableTableAdapter.Fill(this.dataSet1.MyTable);
this.SetCode();
}
//*************************************************************
/// <summary>追加処理を実行します</summary>
//*************************************************************
public void Add() {
this.InvalidCode();
if (this.bindingSource1.Find("番号", this.Code) >= 0) {
throw new Exception("既に登録されている番号です");
}
object newRow = this.bindingSource1.AddNew();
DataSet1.MyTableRow row = this.GetMyTableRow(newRow);
if (row == null) throw new Exception("追加に失敗しました");
row.番号 = this.Code;
this.bindingSource1.EndEdit();
myTableTableAdapter.Update(this.dataSet1.MyTable);
this.Read();
}
//*************************************************************
/// <summary>更新処理を実行します</summary>
//*************************************************************
public void Update() {
this.InvalidCode();
this.bindingSource1.EndEdit();
this.myTableTableAdapter.Update(this.dataSet1.MyTable);
}
//*************************************************************
/// <summary>削除処理を実行します</summary>
//*************************************************************
public void Delete() {
this.InvalidCode();
this.bindingSource1.RemoveCurrent();
this.bindingSource1.EndEdit();
this.myTableTableAdapter.Update(this.dataSet1.MyTable);
this.SetCode();
}
//*************************************************************
/// <summary>読込み処理を実行します</summary>
//*************************************************************
public void Read() {
int i = this.bindingSource1.Find("番号", this.Code);
if (i < 0) throw new Exception("番号が見つかりません");
this.bindingSource1.Position = i;
this.SetCode();
}
//*************************************************************
/// <summary>番号値が有効かどうかを検証した結果を取得します
/// </summary>
//*************************************************************
private void InvalidCode() {
if (this.Code > 0 || this.Code < 100000000) return;
throw new Exception("番号が有効な値ではありません");
}
//*************************************************************
/// <summary>現在行のコード値をテキストボックスに設定します
/// </summary>
/// <remarks>現在行が null ならゼロに設定します</remarks>
//*************************************************************
private void SetCode() {
DataSet1.MyTableRow row =
this.GetMyTableRow(this.bindingSource1.Current);
if (row == null) {
this.Code = 0;
return;
}
this.Code = row.番号;
}
//*************************************************************
/// <summary>DataSet1.MyTableRow 型に変換した結果を取得します
/// </summary>
/// <param name="value">変換したい値</param>
/// <returns>DataSet1.MyTableRow 型に変換した結果</returns>
/// <remarks>変換できない場合は null 値を返します</remarks>
//*************************************************************
private DataSet1.MyTableRow GetMyTableRow(object value) {
DataRowView v = value as DataRowView;
if (v == null) return null;
return v.Row as DataSet1.MyTableRow;
}
}
}
中で使用するオブジェクトが異なるため、
クラスの継承について
public partial class Logic : Component, INotifyPropertyChanged
基本クラスがComponentになっています。
C#では継承できるクラスは1つだけになるので、
そこで、
コンストラクタ
今回のコンストラクタは、
public Logic() {
InitializeComponent();
}
public Logic(IContainer container) {
container.Add(this);
InitializeComponent();
}
C#では、
BindingSourceプロパティ
VB6では、
public System.Windows.Forms.BindingSource BindingSource {
get { return this.bindingSource1; }
}
BindingSourceはフォーム上のユーザーコントロールとバインドさせる必要があるため、
DataSetのデータを充填する
フォームが開いたタイミングで、
public void Fill() {
this.myTableTableAdapter.Fill(this.dataSet1.MyTable);
this.SetCode();
}
this.
追加処理
bindingSource1のFindメソッドによって、
要素番号が0以上なら、
public void Add() {
this.InvalidCode();
if (this.bindingSource1.Find("番号", this.Code) >= 0) {
throw new Exception("既に登録されている番号です");
}
object newRow = this.bindingSource1.AddNew();
DataSet1.MyTableRow row = this.GetMyTableRow(newRow);
if (row == null) throw new Exception("追加に失敗しました");
row.番号 = this.Code;
this.bindingSource1.EndEdit();
myTableTableAdapter.Update(this.dataSet1.MyTable);
this.Read();
}
その後、
最後に、
読み込み
this.bindingSource1.Position = i;
Positionプロパティに要素番号値を格納することで、
Codeプロパティに値をセットする
bindingSource1オブジェクトのCurrentプロパティは、
DataSet1.MyTableRow row =
this.GetMyTableRow(this.bindingSource1.Current);
if (row == null) {
this.Code = 0;
return;
}
this.Code = row.番号;
このレコードの番号の値をCodeプロパティにセットしています。
型の変換
以下は、
private DataSet1.MyTableRow GetMyTableRow(object value) {
DataRowView v = value as DataRowView;
if (v == null) return null;
return v.Row as DataSet1.MyTableRow;
}
C#はタイプセーフな言語です。
objectはすべての型から継承されている型なので、
一方で、
ただし、
DataRowView v = value as DataRowView;
上記のコードはas演算子を使って、
Form1の作成
Form1は、
Logicコンポーネントの配置
Form1のフォームエディタを開いて、
なお、
コードの作成
コードは以下の通りです。
using System;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
//*************************************************************
/// <summary>電話帳サンプルソフトフォーム</summary>
//*************************************************************
public partial class Form1 : Form
{
//*************************************************************
///<summary>コンストラクタ</summary>
//*************************************************************
public Form1() {
this.InitializeComponent();
this.codeTextBox.DataBindings.Add(
"Text", this.logic, "Code");
this.nameTextBox.DataBindings.Add(
"Text", this.logic.BindingSource, "名前");
this.telephoneNumberTextBox.DataBindings.Add(
"Text", this.logic.BindingSource, "電話番号");
}
//*************************************************************
// イベント処理用メソッド
//*************************************************************
private void addButton_Click(object sender, EventArgs e) {
try {
this.logic.Add();
}
catch(Exception ex) {
MessageBox.Show(ex.Message);
}
}
private void closeButton_Click(object sender, EventArgs e) {
this.Close();
}
private void Form1_Load(object sender, EventArgs e) {
this.logic.Fill();
}
private void readButton_Click(object sender, EventArgs e) {
try {
this.logic.Read();
}
catch(Exception ex) {
MessageBox.Show(ex.Message);
}
}
private void updateButton_Click(object sender, EventArgs e) {
try {
this.logic.Update();
}
catch(Exception ex) {
MessageBox.Show(ex.Message);
}
}
private void deleteButton_Click(object sender, EventArgs e) {
try {
this.logic.Delete();
}
catch(Exception ex) {
MessageBox.Show(ex.Message);
}
}
}
}
基本的には、
コンストラクタ
今回も、
this.nameTextBox.DataBindings.Add(
"Text", this.logic.BindingSource, "名前");
this.telephoneNumberTextBox.DataBindings.Add(
"Text", this.logic.BindingSource, "電話番号");
バインディングするオブジェクトは、
フォームロードイベント時の処理
以下のコードによって、
private void Form1_Load(object sender, EventArgs e) {
this.logic.Fill();
}
最後に
今回は、
本連載は、
VB6で実際に活躍されているプログラマの方に向けた内容ということもあり、
本連載を読んでくださった多くの方がC#によるプログラミングを楽んでいただけることを願っています。
最後に、
ありがとうございました。