LINQ to Object
LINQ to SQL
アプリケーションのアイコンの設定
画像の配置
アプリケーションの実行ファイルの作成
1
2
3
4
5
第
章
この章では、Visual Studio
2008の新機能「LINQ」を
使用して、MyScheduleア
プリケーションのデータを
データベースから読み込む
方法を理解します。また、
ユーザーインターフェイス
を完成させて、アプリケー
ションを仕上げます。
の仕上げ
10
この章では、予定リストボックスに表示されるデータの並べ替えやデータベースからデータを読み 込む方法を学習します。また、フォームに画像を挿入する方法やアイコンを作成してそのアイコンを アプリケーションに設定する方法も学習します。 ●データの並べ替えを行う ●データベースを使用する ●アプリケーションにアイコンを設定する ●フォームに画像を配置する ●アプリケーションの実行ファイルを作成する 10:00∼10:30 予定1 11:00∼11:30 予定3 14:00∼15:00 予定2 10:00∼10:30 予定1 14:00∼15:00 予定2 11:00∼11:30 予定3 並べ替え 表示 11:00∼11:30 予定3 登録 その日の予定リストや長期の予定リストを開始 日付の項目を基準に並べ替えて表示する方法を 学習します。 ここで、LINQ to ObjectやLINQ to SQLを 理解します。 開発はデバッグモードで、配布はリリースモードで行います。
LINQ to Object
1
LINQを使用することで、IEnumerableやXML、リレーショナルデータベースなど、さまざまなデータソ ースに、共通の構文で問い合わせを行うことができます。ここでは、LINQ to Objectを利用して、予定リ ストに登録されている予定オブジェクトを日付の昇順で表示します。LINQ機能を利用してソートを行う
予定リストオブジェクトに登録されている予定を順番にリストボックスに表示します。このとき、予定リ ストボックスの予定データを開始日付時刻の昇順になるように表示します。開始日付時刻が同じ場合は、終 了日付時刻の昇順になるように表示します。q
「Form1.cs」のコードを表示する。w
RefreshListBoxメソッドを次のように変更する(色文字部分)。private void RefreshListBox() { scheduleListBox.Items.Clear(); if (listitem.Shortflg) { label5.Text = "時間 件名 内容"; var sortshortitems =
from shorttable in listitem.GetCurrentShortitems(startdate) orderby shorttable.StartDateTime, shorttable.EndDateTime select shorttable;
foreach (ShortItem s in sortshortitems) scheduleListBox.Items.Add(s.Itemall); } else { label5.Text = "期間 件名 内容"; var sortlongitems =
from longtable in listitem.GetCurrentLongitems(startdate) orderby longtable.StartDateTime, longtable.EndDateTime select longtable;
foreach (LongItem l in sortlongitems) scheduleListBox.Items.Add(l.Itemall); } //省略 }
1
2
3
4
e
MainFormのフォームデザイナを表示する。r
[登録]ボタンをダブルクリックする。 inputButton_Clickイベントハンドラが表示 される。t
inputButton_Clickイベントハンドラを次のように 変更する(色文字部分)。ただし、RefreshListBox メソッドで変更したコードと同じなので、解説は 省略する(手順w参照)。 //登録ボタンのClickイベントハンドラprivate void inputButton_Click(object sender, EventArgs e) {
//件名と内容が入力されているかどうかのチェック
if (subjectTextBox.Text != "" && contentTextBox.Text != "") { //省略 //その日の予定 if (startTextBox.Text == endTextBox.Text) { listitem.Shortflg = true; shortMenu.Checked = true; longMenu.Checked = false; label5.Text = "時間 件名 内容"; ShortItem shortitem = new ShortItem(startTextBox.Text,
starttimeDomainUpDown.Text, endtimeDomainUpDown.Text, subject, contents); if (listitem.AddShortitems(shortitem)) { scheduleListBox.Items.Clear(); var sortshortitems =
from shorttable in listitem.GetCurrentShortitems(startdate) orderby shorttable.StartDateTime, shorttable.EndDateTime select shorttable;
foreach (ShortItem shorts in sortshortitems) scheduleListBox.Items.Add(shorts.Itemall); } else MessageBox.Show("既に存在する予定です", "その日の予定エラー"); } //長期の予定 else { listitem.Shortflg = false; shortMenu.Checked = false; longMenu.Checked = true; label5.Text = "期間 件名 内容"; LongItem longitem = new LongItem(startTextBox.Text,
endTextBox.Text, subject, contents); if (listitem.AddLongitems(longitem)) {
y
[デバッグ開始]ボタンをクリックしてプログ ラムを実行する。[予定ファイル読み込み]メ ッセージは[いいえ]をクリックする。u
[表示]メニューの[その日の予定]をクリッ クする。i
開始時刻に13:00、終了時刻に13:30を指定し、 件名にtest2、内容にテストと入力して、[登録] ボタンをクリックする。o
開始時刻に10:00、終了時刻に13:00を指定し、 件名にtest1、内容にテストと入力して、[登録] ボタンをクリックする。 test1の予定、test2の予定の順に表示される。 scheduleListBox.Items.Clear(); var sortlongitems =from longtable in listitem.GetCurrentLongitems(startdate) orderby longtable.StartDateTime, longtable.EndDateTime select longtable;
foreach (LongItem longs in sortlongitems) scheduleListBox.Items.Add(longs.Itemall); } else MessageBox.Show("既に存在する予定です", "長期の予定エラー"); } ClearSubject(); //件名と内容消去 } else { MessageBox.Show("件名と内容を入力してください", "予定登録エラー"); } }
!0
test1の予定をクリックして、[修正]ボタンを クリックする。 [予定の修正]フォームが表示される。!1
開始時刻を13:30、終了時刻を14:30に変更し て、[OK]ボタンをクリックする。 test2の予定、test1の予定の順に表示され る。!2
フォームの閉じるボタンをクリックする。 ヒント クエリ式 リストや配列から条件式に合うオブジェクトのメ ンバを取り出す構文は以下のようになります。 IEnumerable<クラス型> オブジェクト名 = from 変数名 in リストや配列 where 条件式 select 変数名から取り出したいメンバLINQを使用すると、その日の予定リストオブジェクトに対してデータベース操作構文のようなクエリ 式を用いて、開始日付時刻の昇順に並べ替えることができます。同じ開始日付時刻のときは、終了日付時 刻の昇順で並べ替えを行います。その結果を変数sortshortitemsに取り出します。
「var sortshortitems」は、「IEnumerable<ShortItem> sortshortitems」のことです。 LINQのクエリ式は以下のような構文になります。 var 変数名= from 変数 in リストや配列 where 条件式 orderby 並べ替えの基準となる項目 select 取り出したい項目 var sortshortitems =
from shorttable in listitem.GetCurrentShortitems(startdate) orderby shorttable.StartDateTime, shorttable.EndDateTime select shorttable;
1
foreachステートメントを使い、zで並べ替えた予定リストの結果からその日の予定オブジェクトを取 り出し、予定リストボックスに登録します。
foreach (ShortItem s in sortshortitems) scheduleListBox.Items.Add(s.Itemall);
2
長期の予定リストオブジェクトに対して、クエリ式を用いて、開始日付の昇順で並べ替えを行います。 同じ開始日付のときは終了日付の昇順で並べ替えを行います。その結果を変数sortlongitemsに取り出し ます。 var sortlongitems =from longtable in listitem.GetCurrentLongitems(startdate) orderby longtable.StartDateTime, longtable.EndDateTime select longtable;
3
foreachステートメントを使い、cで並べ替えた予定リストの結果から長期の予定オブジェクトを取り 出し、予定リストボックスに登録します。
foreach (LongItem l in sortlongitems) scheduleListBox.Items.Add(l.Itemall);
4
LINQ to SQL
2
アプリケーション設定ファイル(myinit.txt)にデータベース使用が記述されているときは、データベー スからデータを取り出し、終了するときもデータベースにデータを書き込みます。ここではリレーショナル データベースへの問い合わせにLINQ to SQLを使用します。LINQ to SQLを使用すると、SQL Server のデ ータをプログラムから操作できます。
q
myinit.txtファイルの最終行に、「USE=DATABASE」を追加する。 DISP=SHORT SHORT=shortfile.csv LONG=longfile.csv HELP=myschedule.chm USE=DATABASEw
「FileIO.cs」のコードを表示する。e
FileIOクラスに、データベース使用フラグを追加する。また、InitReadメソッドに、アプリケーション設 定ファイルの情報からデータベース使用フラグをオンにするコードを追加する。 class FileIO {public static string shortfile; public static string longfile; public static string myhelp;
public static bool databaseflg = false;
//設定ファイル読み込み
public static void InitRead(ScheduleList list) {
if (File.Exists("myinit.txt")) {
try {
StreamReader reader = new StreamReader("myinit.txt", Encoding.GetEncoding("Shift_JIS")); while(reader.Peek() != -1) { string[] field=reader.ReadLine().Split('='); if (field[0] == "DISP") { if (field[1] == "SHORT") list.Shortflg = true; else list.Shortflg = false; }
データベースを使用する
アプリケーション設定ファイル(myinit.txt)に、データベース使用情報を追加します。1
r
ソ リ ュ ー シ ョ ン エ ク ス プ ロ ー ラ で [MySchedule]を右クリックして、[追加]を ポイントし、[新しい項目]をクリックする。 [新しい項目の追加]ダイアログボックスが 表示される。t
[カテゴリ]ボックスから[データ]をクリッ クし、[テンプレート]ボックスから[サービ スベースのデータベース]をクリックする。y
[ファイル名]ボックスにMyScheduleを入力 し、[追加]をクリックする。 データソース構成ウィザードが起動する。 if (field[0] == "USE") { databaseflg = true; shortfile = null; longfile = null; } if (field[0] == "SHORT") shortfile=field[1]; if (field[0] == "LONG") longfile = field[1]; if (field[0] == "HELP") myhelp = field[1]; } reader.Close(); } catch (FileNotFoundException) { } //例外処理 } } //省略 }2
u
[完了]ボタンをクリックする。 MySchedule.mdfが作成される。i
ソ リ ュ ー シ ョ ン エ ク ス プ ロ ー ラ の [MySchedule.mdf]をダブルクリックする。 サーバーエクスプローラが表示される。o
サーバーエクスプローラの[テーブル]を右ク リックして、[新しいテーブルの追加]をクリ ックする。!0
列名、データ型、Null許容に関して、次の表の とおりにテーブルの定義を行う。!1
[テーブル]のプロパティウィンドウの[(オブ ジェクト名)]の値にSHORTTABLEと入力す る。!2
同様に、新しいテーブルの追加を行い、次のとお りにテ ーブ ル の 定 義 を 行う。 テ ーブ ル 名 に LONGTABLEと入力する。 列名 データ型 Null許容 STARTDATE char(10) × STARTTIME char(5) × ENDTIME char(5) × SUBJECT nchar(20) × CONTENTS nvarchar(50) ×!3
[すべてを保存]ボタンをクリックする。 サーバーエクスプローラの[テーブル]の下 にLONGTABLEとSHORTTABLEが作成され る。 列名 データ型 Null許容 STARTDATE char(10) × ENDDATE char(10) × SUBJECT nchar(20) × CONTENTS nvarchar(50) ×LINQ to SQLクラスを作成する
データベース上のテーブルに相当するクラスを定義し、Table属性を追加します。また、このクラスのメ ンバにはColumn属性を追加します。LINQ to SQLは、これらの属性を見て、クラスのメンバへのアクセス をリレーショナルデータベースへのSQL問い合わせに変換します。q
ソ リ ュ ー シ ョ ン エ ク ス プ ロ ー ラ の [MySchedule]を右クリックして、[追加]を ポイントし、[新しい項目]をクリックする。 [新しい項目の追加]ダイアログボックスが 表示される。w
[カテゴリ]ボックスで[データ]をクリック し、[テンプレート]ボックスで[LINQ to SQLクラス]をクリックする。e
[ファイル名]ボックスにScheduleSQLと入力 し、[追加]をクリックする。 プロジェクトにScheduleSQL.dbmlが追加 される。 静的フィールドdatabaseflgを宣言して、falseを代入します。public static bool databaseflg = false;
1
field[0]がUSEのときは、データベースを使用するので、静的フィールドdatabaseflgにtrueを代入 して、shortfileとlongfileにnullを代入します。 if (field[0] == "USE") { databaseflg = true; shortfile = null; longfile = null; }2
コードの解説
LINQ to SQLを利用する
作成したLINQ to SQLクラスを利用して、データベースからデータを取り出します。
q
「FileIO.cs」のコードを表示する。w
FileIOReadメソッドのコードに、データベースからデータを読み込むコードを追加する(色文字部分)。//予定ファイル読み込み
public static void FileIORead(ScheduleList list) { //省略 try { //その日の予定ファイル読み込み if(shortfile!=null) { //省略 } //長期の予定ファイル読み込み if(longfile!=null) { //省略 } //データベースへの接続 if (databaseflg) {
var db = new ScheduleSQLDataContext();
1
ヒント テーブルのリンク テーブル同士に関係付けを行う場合は、手順rの状態 でツールボックスから[アソシエーション]を選んで、 クラス図のクラスからクラスへドラッグします。関連付 けエディタが表示されるので、このエディタを使って、 プロパティ同士の関係付けを行います。
r
サーバーエクスプローラの[LONGTABLE]と [SHORTTABLE」をScheduleSQL.dbmlの作 業領域にドラッグする。 作業領域にクラス図が表示される。データベ ース上のテーブルに相当するクラスが作成さ れ、データベースに接続するためのクラス (DataContextを継承して作成されたクラス) が作成される。t
サーバーエクスプローラの自動的に隠すをクリ ックする サーバーエクスプローラが折りたたまれる。var shorttable =
from sfield in db.SHORTTABLE select sfield;
foreach (var sfield in shorttable) {
ShortItem s = new ShortItem(sfield.STARTDATE, sfield.STARTTIME, sfield.ENDTIME,
sfield.SUBJECT, sfield.CONTENTS); list.AddShortitems(s);
}
var longtable =
from lfield in db.LONGTABLE select lfield;
foreach (var lfield in longtable) {
LongItem l = new LongItem(lfield.STARTDATE, lfield.ENDDATE, lfield.SUBJECT, lfield.CONTENTS); list.AddLongitems(l); } } } catch (FileNotFoundException) { } //例外処理 }
2
3
4
5
e
FileIOWriteメソッドに、予定リストオブジェクトのデータをデータベースに書き込むコードを追加する (色文字部分)。 using System.Data.Sqlclient; //省略 //予定ファイル書き込みpublic static void FileIOWrite(ScheduleList list) { try { //その日の予定ファイル書き込み //省略 //長期の予定ファイル書き込み //省略 //データベースに書き込む if (databaseflg) {
string basedir = AppDomain.CurrentDomain.BaseDirectory; string ConnectionString =
"Data Source=.¥¥SQLEXPRESS;AttachDbFilename=¥"" + basedir + "MySchedule.mdf¥";Integrated Security=True;User Instance=True"; SqlConnection hConnection = (
new SqlConnection(ConnectionString)); hConnection.Open();
//その日の予定全削除
string SQL = "DELETE FROM SHORTTABLE";
SqlCommand cmd = new SqlCommand(SQL, hConnection); cmd.ExecuteNonQuery();
//長期の予定全削除
SQL = "DELETE FROM LONGTABLE";
6
7
8
9
cmd.ExecuteNonQuery(); //その日の予定登録
foreach (ShortItem s in list.Shortitems) {
string[] field = s.GetField();
SQL = "INSERT INTO SHORTTABLE VALUES('" + field[0] + "'," + "'" + field[1] + "','" + field[2] + "','"
+ s.Subject + "','" +s.Contents + "')"; cmd = new SqlCommand(SQL, hConnection); cmd.ExecuteNonQuery();
}
//長期の予定登録
foreach (LongItem l in list.Longitems) {
string[] field = l.GetField();
SQL = "INSERT INTO LONGTABLE VALUES('" + field[0] + "','" + field[1] + "','" + l.Subject + "','" + l.Contents + "')"; cmd = new SqlCommand(SQL, hConnection);
cmd.ExecuteNonQuery(); } hConnection.Close(); hConnection.Dispose(); } } catch (FileNotFoundException) { } //例外処理 }
12
r
InitWriteメソッドにアプリケーション設定ファイルへのデータ書き込み処理を追加する(色文字部分)。 //設定ファイル書き込みpublic static void InitWrite(ScheduleList list) {
try {
string[] files = new string[3]; //設定ファイルを読み込む
StreamReader reader = new StreamReader("myinit.txt", Encoding.GetEncoding("Shift_JIS"));
while (reader.Peek() != -1) {
string[] field = reader.ReadLine().Split('='); if(field[0] == "SHORT") files[0] = field[1]; if (field[0] == "LONG") files[1] = field[1]; if (field[0] == "HELP") files[2] = field[1]; } reader.Close(); //設定ファイルを書き込む
StreamWriter writer = new StreamWriter("myinit.txt", false,
13
11
Encoding.GetEncoding("Shift_JIS")); if(list.Shortflg) writer.WriteLine("DISP=SHORT"); else writer.WriteLine("DISP=LONG"); if (files[0] != null) writer.WriteLine("SHORT=" + files[0]); if (files[1] != null) writer.WriteLine("LONG=" + files[1]); if (files[2] != null) writer.WriteLine("HELP=" + files[2]); if(databaseflg) writer.WriteLine("USE=DATABASE"); writer.Close(); } catch (FileNotFoundException) { } //例外処理 }
14
ScheduleSQLDataContextクラスは、データベースサーバーに接続するためのクラス(DataContext) を 継 承 し て 自 動 的 に 作 成 さ れ た ク ラ ス で す 。 こ こ で は 、 デ ー タ ベ ー ス に 接 続 す る た め に ScheduleSQLDataContextのインスタンスを生成します。var db = new ScheduleSQLDataContext();
1
このクエリ式は、SHORTTABLEからすべてのレコードを取り出し、shorttableオブジェクトに代入し ます。
var shorttable =
from sfield in db.SHORTTABLE select sfield;
2
xで取り出したレコードを1件ずつ読み込み、その日の予定オブジェクトを作成して、その日の予定リ ストに登録します。
foreach (var sfield in shorttable) {
ShortItem s = new ShortItem(sfield.STARTDATE, sfield.STARTTIME,sfield.ENDTIME, sfield.SUBJECT, sfield.CONTENTS); list.AddShortitems(s); }
3
コードの解説
このクエリ式は、LONGTABLEからすべてのレコードを取り出し、longtableに代入します。 var longtable =from lfield in db.LONGTABLE select lfield;
データベースへ接続するために、SqlConnectionオブジェクトを生成します。 SqlConnection hConnection = ( new SqlConnection(ConnectionString));
7
データベースへ接続します。 hConnection.Open();8
.のSQL文を実行します。 cmd.ExecuteNonQuery();10
その日の予定リストオブジェクトからその日の予定オブジェクトを取り出し、その日の予定テーブルに 1件ずつ登録します。foreach (ShortItem s in list.Shortitems) {
string[] field = s.GetField();
SQL = "INSERT INTO SHORTTABLE VALUES('" + field[0] +"'," + "'" + field[1] + "','" + field[2] + "','"
+ s.Subject + "','" + s.Contents + "')"; cmd = new SqlCommand(SQL, hConnection); cmd.ExecuteNonQuery();
}
11
変数SQLには、「その日の予定のテーブルからすべてのレコードを削除する」というSQL文が代入され ています。ここでは、このSQL文を実行するためのcmdオブジェクトを生成します。
SqlCommand cmd = new SqlCommand(SQL, hConnection);
9
vで取り出したレコードを1件ずつ読み込み、長期の予定オブジェクトを作成して、長期の予定リスト に登録します。
{
LongItem l = new LongItem(lfield.STARTDATE, lfield.ENDDATE, lfield.SUBJECT, lfield.CONTENTS);
list.AddLongitems(l); }
変数 basedirに、アプリケーションが起動しているディレクトリの絶対パスを代入します。変数 ConnectionStringにはデータベースへの接続文字列を代入します。
string basedir = AppDomain.CurrentDomain.BaseDirectory; string ConnectionString =
"Data Source=.¥¥SQLEXPRESS;AttachDbFilename=¥"" + basedir + "MySchedule.mdf¥";Integrated Security=True;User Instance=True";
データベースへの接続を解除します。 hConnection.Close(); hConnection.Dispose();
12
myinit.txtファイルを読み込みます。データベースを使用するときは、その日の予定ファイルの変数も 長期の予定ファイルの変数もnullを設定しているので、再度、予定ファイル名を読み込みます。StreamReader reader = new StreamReader("myinit.txt", Encoding.GetEncoding("Shift_JIS"));
13
string配列filesの0番目にはその日の予定ファイル名が、1番目には長期の予定ファイル名が、2番目に はヘルプのファイル名が代入されているので、それぞれのデータの前に各種ファイルの意味を表す文字列 と一緒にファイルに書き込みます。また、データベース使用フラグがtrueのときは「USE=DATABASE」 とファイルに書き込みます。 if (files[0] != null) writer.WriteLine("SHORT=" + files[0]); if (files[1] != null) writer.WriteLine("LONG=" + files[1]); if (files[2] != null) writer.WriteLine("HELP=" + files[2]); if(databaseflg) writer.WriteLine("USE=DATABASE");14
アプリケーションのアイコンの設定
3
MyScheduleアプリケーションにアイコンを設定して、エクスプローラやタスクバーで作成したアイコン が表示されるようにします。また、各フォームのタイトルバーにもアイコンを設定します。ここでは、アイ コンの作成と設定の方法について説明します。アイコンの作成
「イメージエディタ」を使って、MyScheduleアプリケーションに設定するアイコンを作成します。q
[表示]メニューの[ツールバー]をポイント し、[イメージエディタ]をクリックする。 [イメージエディタ]ツールバーが表示され る。w
ソリューションエクスプローラの[MySchedule] を右クリックする。e
[追加]をポイントして、[新しい項目]をクリ ックする。 [新しい項目の追加]ダイアログボックスが 表示される。r
[カテゴリ]ボックスで[Visual C#アイテム] をクリックし、[テンプレート]ボックスで [アイコンファイル]をクリックする。t
[ファイル名]ボックスにアイコンファイル名 を入力する。ここでは「Icon1.ico」のままと する。y
[追加]をクリックする。 「Icon1.ico」ファイルが作成される。ヒント カラフルなアイコンを作りたい場合 256色のアイコンを作ることもできます。[イメー ジ]メニューの[新しいイメージタイプ]をクリッ クし、[アイコンイメージタイプの新規作成]ダイ アログボックスで[32×32、8ビット]を選択して [OK]をクリックします。256色以上の色のパソコ ンで表示した場合、こちらのアイコンが表示され ます。
u
[イメージエディタ]ツールバーの[鉛筆ツー ル]ボタンや[色]ウィンドウなどを使って、 アイコンを作成する。サイズの違うアイコンの作成
作成したIcon1.icoアイコンには、「16×16」と「32×32」(単位はピクセル)の2つのタイプのアイコンが 含まれます。「32×32」のアイコンがアイコン表示などで使われる大きいアイコン、「16×16」アイコンが タイトルバー、タスクバーのアイコンとして表示される小さいアイコンです。「16×16」アイコンがない場 合は「32×32」アイコンが縮小されて利用されます。q
左側の「32×32,4ビット,BMP」をクリッ クする。 「32×32」のアイコンが表示される。w
左側の「16×16,4ビット,BMP」をクリッ クする。 「16×16」のアイコンが表示される。e
[標準]ツールバーの[Icon1.icoの保存]ボタ ンをクリックする。 作成したアイコンが保存される。アプリケーションにアイコンを設定する
MyScheduleアプリケーションに作成したIcon1.icoアイコンを設定します。エクスプローラやタスクバー でMySchedule.exeを確認すると、設定したアイコンが表示されます。なお、イメージエディタで作成した アイコンだけでなく、既存のアイコンファイルを読み込んで使用することも可能です(ヒント参照)。q
[プロジェクト]メニューの[MyScheduleの プロパティ]をクリックする。w
[アプリケーション]が選択されていることを 確認し、[アイコン]ボックスの▼をクリック する。 [(既定のアイコン)]と作成した[Icon1.ico] が表示される。e
[Icon1.ico]を選択する。r
[デバッグ開始]ボタンをクリックしてプログ ラムを実行し、フォームの閉じるボタンで終了 する。t
MyScheduleプロジェクトのフォルダの中にあ る 「 ¥ b i n ¥ D e b u g 」 フ ォ ル ダ を 開 き 、 MySchedule.exeファイルに作成したIcon1.ico ファイルが利用されていることを確認する。 ヒント 既定のアイコンファイルを利用するには 手順wで[アイコン]ボックスの右側にある[...] ボタンをクリックし、他の場所にあるアイコンフ ァイルを選択します。 一覧または詳細表示で使われるアイコン 手順tでフォルダウィンドウの[表示]メニュー の[一覧]または[詳細]をクリックしてファイル の表示形式を変更した場合、ファイル名の左側に 「16×16」アイコンが表示されます。フォームにアイコンを設定する
MyScheduleアプリケーションで表示される各種フォームのタイトルバーのアイコンとして、作成した Icon1.icoアイコンを設定します。q
MainFormフォームをフォームデザイナで表示 し、フォームをクリックして選択する。 プロパティウィンドウにMainFormのプロパ ティが表示される。w
Iconプロパティをクリックし、右側の[...]ボ タンをクリックする。 [ファイルを開く]ダイアログボックスが表 示される。e
作成したアイコンを選択して、[開く]をクリ ックする。作成したIcon1.icoはMySchedule プロジェクトのフォルダの中に保存されてい る。 Iconプロパティとフォームのタイトルバーに、 作成したアイコンが表示される。r
同 様 に し て 、 D i s p l a y F o r m フ ォ ー ム と UpdateFormフォームのIconプロパティにも作 成したアイコンを設定する。t
[デバッグ開始]ボタンをクリックしてプログ ラムを実行する。 MainFormフォームのタイトルバーに作成し たアイコンが表示される。y
フォームの閉じるボタンをクリックする。 ヒント 設定したアイコンを削除する Iconプロパティに設定したアイコンを削除するに は、I c o n プロパティの右側の欄をクリックし、 dを押します。これで既定のアイコンに戻りま す。画像の配置
4
VersionFormフォームに独自の画像を追加します。ここでは、画像を作成して設定する方法について説 明します。画像の作成
画像ファイルを新規に作成し、「イメージエディタ」を利用して画像を作成します。q
ソリューションエクスプローラの[MySchedule] を右クリックする。w
[追加]をポイントし、[新しい項目]をクリッ クする。 [新しい項目の追加]ウィンドウが表示され る。e
[テンプレート]ボックスの[ビットマップフ ァイル]をクリックする。r
[ファイル名]ボックスに画像ファイル名を入 力する。ここでは「Bitmap1.bmp」のままと する。t
[追加]をクリックする。 「Bitmap1.bmp」ファイルが作成される。y
[イメージエディタ]ツールバーの[鉛筆ツー ル]ボタンや[色]ウィンドウなどを使って画 像を作成する。u
[Bitmap1.bmpの保存]ボタンをクリックす る。 作成した画像が保存される。フォームに画像を挿入する
VersionFormフォームに作成したBitmap1.bmpファイルを挿入します。なお、あらかじめペイントソフ トなどで作成しておいた画像やデジタルカメラで撮影した写真などを読み込むことも可能です(ヒント参 照)。q
VersionFormフォームのフォームデザイナを 表示する。w
ツールボックスの[PictureBox]を選択して フォームにドロップする。 pictureBox1が配置される。e
プロパティウィンドウのImageプロパティをク リックし、右側の[...]ボタンをクリックす る。 [リソースの選択]ダイアログボックスが表 示される。r
[プロジェクトリソースファイル]をクリック して選択する。t
[インポート]をクリックする。 [開く]ダイアログボックスが表示される。y
インポートしたい画像ファイルを選択して[開 く]をクリックする。作成したBitmap1.bmp はMyScheduleプロジェクトのフォルダの中に 保存されている。u
[OK]をクリックする。 PictureBoxコントロールにBitmap1.bmpが 表示される。i
SizeModeプロパティの値をAutoSizeに設定す る。 PictureBoxコントロールの大きさが画像と 同じ大きさになる。o
[デバッグ開始]ボタンをクリックしてプログ ラムを実行する。!0
[ヘルプ]メニューの[バージョン情報]をク リックする。 作成した画像が表示される。!1
[閉じる]ボタンをクリックする。!2
フォームの閉じるボタンをクリックする。 ヒント PictureBoxの画像サイズを調整する SizeModeプロパティにAutoSizeが設定されてい ると、PictureBoxコントロールが画像と同じ大き さに調整されます。CenterImageが設定されてい ると、PictureBoxコントロールの中央に配置され ます。StreachImageが設定されていると、画像の 大きさがPictureBoxコントロールの大きさに合わ せて拡大または縮小されます。 既存の画像を読み込むには あらかじめ作成しておいた画像やデジタルカメラ で撮影した写真の画像などを読み込むには、手順 rで[ローカルリソース]をクリックして[インポ ート]をクリックします。[開く]ダイアログボッ クスで読み込みたいファイルを選択して[開く]を クリックし、[リソースの選択]ダイアログボック スで[OK]をクリックします。アプリケーションの実行ファイルの作成
5
MyScheduleアプリケーションの実行ファイルを作成する方法について説明します。実行ファイルを作成する
今までは「デバッグモード」でMyScheduleプロジェクトのビルドを行っていたので、MyScheduleプロ ジェクトのフォルダにある「¥bin¥Debug」フォルダにMySchedule.exeファイルが作成されていました。 配布するときには「リリースモード」でMyScheduleプロジェクトをビルドします。q
[標準]ツールバーの[ソリューション構成] ボックスの▼をクリックする。 [Debug]、[Release]、[構成マネージャ] が表示される。w
[Release]をクリックする。e
[ビルド]メニューの[MyScheduleのビルド] をクリックする。 MyScheduleプロジェクトのフォルダの中に あ る「 ¥ b i n ¥ R e l e a s e 」フ ォ ル ダ に MySchedule.exeファイルが作成される。 ヒント デバッグモードとリリースモード デバッグモードは、アプリケーションを開発すると きに使うモードです。デバッグモードで作成した 実行ファイルにはデバッグ(エラーの修正など)に 必要な情報が付随しているため、サイズが大きく なります。 リリースモードは、アプリケーションを配布すると きに使うモードです。リリースモードで作成した 実行ファイルは、ユーザーが快適に使用できるよ うに最適化が行われます。また、実行ファイルの サイズが小さくなり、アプリケーションの実行速 度が向上します。C# 3.0の特長
C
コ ラ ム
Visual Studio 2008では、.Net Frameworkのバージョンが3.5に、C#のバージョンが3.0に変更さ れました。ここでは、C# 3.0の新機能について説明します。
var
キーワードと拡張メソッド
varキーワードを用いて、暗黙的に型付けされたローカル変数を定義できます。var宣言された変 数は、値を代入することで型を特定します。明示的に型を知りたい場合は「var」の上にマウスポイ ンタを置くと、ツールチップの情報として表示されます。 var x = 1; var y = 1.0; var z = "abcde"; var宣言した変数1
2
3
z変数xは、1が代入され、整数を表すint型に設定される。 x変数yは、1.0が代入され、64ビット浮動小数点数を表すdouble型に設定される。 c変数zは、「abcde」が代入され、文字列を表すstring型に設定される。 zIndexString拡張メソッドを宣言する。必ず第1引数にはthisを使用する。 x zで宣言したIndexStringメソッドを呼び出す。従来の呼び出し方法であれば「Extensions. IndexString(str)」と記述する。static class Extensions {
public static string IndexString(this string s){ 処理内容記述(略) } } 拡張メソッドの宣言 string str = "Hello C#"; string s1 = str.IndexString(); 拡張メソッドの呼び出し
1
2
拡張メソッドは、インスタンスメソッド構文を使用して呼び出すことができる静的メソッドです。 拡張メソッドを使用すると、既存の型や構築された型にメソッドを追加できます。拡張メソッドの 宣言は、第1引数の修飾子としてキーワードthisを指定します。ラムダ式
ラムダ式は、メソッドを変数と同列に扱う手法のことです。デリゲートに対して代入すると、匿 名メソッドと同じ扱いとなり、Expression型の変数に代入すると、式ツリー型のデータになります。 ラムダ式は引数リスト、それに続く=>トークン、および、式またはステートメントブロックと して記述します。ラムダ式のパラメータは、明示的に型指定することも暗黙的に型指定することも できます。LINQ
機能
LINQとは、Language Integrated Queryを略したもので、リレーショナルデータベースやXMLに 対する操作をプログラミング言語に統合するものです。C#では、SQLのようなデータベースを操作 する構文が用意されました。本書でもこの機能を利用して、データの並べ替えなどを行います。
Func<int, bool> result = n => n > 0;
ラムダ式を使った匿名メソッド
1
MessageBox.Show(result(-1) + "です"); ラムダ式を使った匿名メソッドを利用した例2
z引数が0よりも大きいときにTrueを、0以下のときにFalseを求める匿名メソッドである。 x zで定義した匿名メソッドを利用する。引数が−1なので「Falseです」というメッセージがメッ セージボックスに表示される。 var 商品マスタ= new[]{new{番号=1,商品名="ワープロ"}, new{番号=2,商品名="パソコン"}, new{番号=3,商品名="プリンタ"}, }; var 指定商品= from p in 商品マスタ where p.番号==2 select p.商品名; foreach (var 商品 in 指定商品) { MessageBox.Show(商品); } LINQ機能を利用した例1
2
3
znumberプロパティを作成する。 xnumberプロパティに12345を代入する。 cnumberプロパティの値を取り出し、メッセージボックスに表示する。 xクエリ式を作成して、商品マスタテーブルから番号が2の商品名を指定商品レコードとして取り出 す。 c指定商品レコードより商品を取り出し、メッセージボックスに表示する。
public int number { get; set; }
自動プロパティ number=12345; MessageBox.Show(number+"です"); プロパティを利用した例
その他の新機能
自動プロパティの機能を利用すると、setメソッドやgetメソッドを作成しなくても、「get;set;」を 記述することで、プロパティが自動的に作成されます。 他にも部分クラス内限定で、メソッドにpartialキーワードを付けることでメソッドの宣言と定義 を分けることができる部分メソッドという機能が追加されています。クラスや構造体、インターフ ェイスの定義は複数のソースファイルに分割できます。この分割にはpartialキーワードを使用し、 分割したクラスを部分クラスと言います。部分クラスはアプリケーションのコンパイル時に結合さ れます。1
2
3
z番号項目と商品名項目を持つ商品マスタテーブルを定義し、その中に以下のデータを代入する。 番号 商品名 1 ワープロ 2 パソコン 3 プリンタよく利用するクラスライブラリ
C
コ ラ ム
System名前空間
コンソールに対する入出力を行うConsoleクラスや数学関連の処理を行うMathクラスをはじめ、 一般的に使用される非常に多数のクラスや構造体、デリゲートなどを提供します。 Consoleクラスは、コンソールから文字を読み込んだり、コンソールに文字を書き込んだりするメ ソッドを提供するクラスです。コンソールから読み込むデータは標準入力ストリームから読み込まれ、 コンソールに書き込むデータは標準出力ストリームに書き込まれます。 Mathクラスは、三角関数や対数関数などの一般的な数値関数の定数と静的メソッドを提供します。 Randomクラスは、乱数についての統計的な要件を満たす数値系列を生成するデバイスを表します。 StringクラスやDateTime構造体など、利用すると便利なクラスや構造体などが.NET Framework のクラスライブラリとしてまとめて管理されています。このクラスライブラリをいかに上手に使用で きるかが、プログラミングの生産性を左右します。 ここでは、よく利用するクラスライブラリを何点か紹介します。 ■Consoleクラスのメンバ例 メンバ例 内容 ReadLine 標準入力ストリームから1行分の文字列を読み取る WriteLine 指定したデータを標準出力ストリームに書き込み、続けて現在の行終端記号を 書き込む ■Mathクラスのメンバ例 メンバ例 内容 Abs 引数で指定した値の絶対値を求める Ceiling 引数で指定した値以上のうち最小の整数を求める Floor 引数で指定した値以下のうち最大の整数を求める Max 指定した2つの値のうち、大きい値を求める Min 指定した2つの値のうち、小さい値を求める PI 円周率を表す Pow 第1引数の値を第2引数の値で累乗した結果を求める Sign 指定した値の符号を示す値を求める。負のときに-1、正のときに1、0のときに0 Sqrt 指定した数値の平方根を求める■Randomクラスのメンバ例 メンバ例 内容 Random 時間に応じて決定される既定の種を使用し、新しいインスタンスを初期化する Next 指定した最大値より小さい0以上の乱数を求める