GUIプログラミングの基本=イベント イベントとは イベントの例 ウィンドウやウィンドウ内のパーツ(ボタン・スクロールバーなど)に発生する 様々な出来事・きっかけ MouseEnterイベント発生 MouseLeaveイベント発生 イベントの例 マウスがウィンドウ上に入った マウスがウィンドウ上から出た マウスのボタンが押された キーボードのキーが押された ウィンドウが閉じられた ウィンドウが開かれた ウィンドウのサイズが変わった 他のウィンドウの下になっていたウィンドウ全体が前に出た 他のウィンドウに隠れていた一部分が前に出た MouseDownイベント発生 このタイプのイベントが発生したらプログラムはウィンドウ内の文字や図形を描かなければならない → Paint イベント発生 ウィンドウが隠れて出たり,サイズが変わったりするたびにウィンドウ内を描画するのか? 答え: YES! それがウィンドウプログラミングの基本
マウスの関係する処理 マウスがウィンドウ上に入ってきたらウィンドウの背景色を赤にする namespace Matsushima { using System.Windows.Forms; using System.Drawing; using System; class MyWindow : Form { public MyWindow() {} protected override void OnMouseEnter(EventArgs ea) { this.BackColor = Color.Red; } protected override void OnMouseLeave(EventArgs ea) this.BackColor = DefaultBackColor; } class koushu8d public static void Main() MyWindow mw = new MyWindow(); mw.Text = "これは松島のウィンドウだ"; mw.Height = 100; mw.Width = 500; Application.Run(mw); } マウスがウィンドウ上に入ってきたらウィンドウの背景色を赤にする マウスがウィンドウ上から出て行ったらウィンドウの背景色を元に戻す 注)このソースのコンパイルと実行には, System.Windows.Forms.dll,Sysutem.dll, System.Drawing.dllへの参照設定が必要
GUIプログラムの実行方式=イベント駆動(イベントドリブン) イベント発生のタイミングも順序も予測不能 非GUIプログラム GUIプログラム class koushu8 { public static void Main() { int x,i ; x = x + 10; Console.WriteLine(・・・); for(i = 0; i < 10; i++) { ・・・・ } if (x > 20) ・・・・ } } class koushu8 { public static void Main() { MyWindow mw = new MyWindow(); mw.Text = "題名"; mw.Height = 100; mw.Width = 500; Application.Run(mw); } } 予測可能な一定の順序で処理が進む イベントA発生 イベントA 処理 イベントループ プログラム終了 イベントB発生 イベントB 処理 ウィンドウクローズイベント発生 イベントC発生 イベントC 処理 イベントを処理するルーチン → イベントハンドラ GUIではプログラマの仕事のほとんどはイベントハンドラの作成!
コントロールを使おう ウィンドウ内を描画するPaintハンドラを作成するのはタイヘン 通常のウィンドウズアプリケーションは,ボタンやテキストボックスなどの一定のコンポーネント(部品)でできている クラスControlはクラスFormのベースクラス クラスControlはコンポーネント・オブジェクトを提供するベースクラス 特徴 コントロールのPaintハンドラを作成する必要はない → すでにControlクラスで定義済み ほとんどの処理はコントロールのプロパティの設定・取得でできる クリックやマウスダウン,キーダウンなどほとんどの全てのイベントのイベントハンドラをプロテクトメソッドとして持っている → 基本的なイベントは自動的に処理される → 独自のイベントハンドラを作成するにはそれを オーバーライドすればよい
いろいろなコントロール ラベル(Label) リストボックス (ListBox) 文字列リストを選択する ボタン(Button) チェックボックス(CheckBox) いくつ選択しても構わない コンボボックス (ConboBox) 文字列リストを選択する グループボックス(GourpBox) ラジオボタンを中に入れる枠 タブコントロール (TabControl) ラジオボタン (RadioButton) 一つだけを選択できる 数値アップダウン (NumericUpDown) 数値を入力する スライダ(TrackBar) テキストボックス (TextBox) 文字列を入力する 「選択する」=「チェックする」
イベントハンドラ以外のプログラミング 起動した時点での日付と時刻を表示するアプリケーション このボタンを押すとアプリケーションを終了
(name)はプロパティではなく,インスタンス(変数)の名前になる. フォームのデザイン Labelコントロール変更点 (name): labelDate Font Size: 18pt TextAlign: MiddleCenter Labelコントロール変更点 (name): labelTime Font Size: 20pt TextAlign: MiddleCenter Buttonコントロール変更点 (name): buttonFinish Text: 終了 Font Size: 12pt (name)はプロパティではなく,インスタンス(変数)の名前になる.
フォームデザイナが自動作成するソース Form1クラスのプライベートメンバの宣言 Font設定等,フォームデザイナで設定した他のプロパティはどこで変更されているのか? using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; namespace Koushu80 { /// <summary> /// Form1 の概要の説明です。 /// </summary> public class Form1 : System.Windows.Forms.Form /// 必要なデザイナ変数です。 private System.ComponentModel.Container components = null; private System.Windows.Forms.Label labelDate; private System.Windows.Forms.Label labelTime; private System.Windows.Forms.Button buttonFinish; public Form1() // // Windows フォーム デザイナ サポートに必要です。 InitializeComponent(); // TODO: InitializeComponent 呼び出しの後に、コンス・・ } /// <summary> /// 使用されているリソースに後処理を実行します。 /// </summary> protected override void Dispose( bool disposing ) { if( disposing ) if (components != null) components.Dispose(); } base.Dispose( disposing ); Windows Form Designer generated code /// アプリケーションのメイン エントリ ポイントです。 [STAThread] static void Main() Application.Run(new Form1()); 正解: この中で変更されている! 通常は表示されないので,見たい場合は + をクリック. ただし,変更しないこと Formクラスから派生したForm1クラスの定義 Main()メソッド Form1クラスのコンストラクタ 静的メソッドApplication.Run()でフォームを起動 フォームデザイナで設定した三つのコントロールに対応するインスタンスの宣言. インスタンス名(変数名)がnameの設定になっている
日付と時間を扱うクラスライブラリ コンソール用のプログラム using System; class Koushu9 { public static void Main() DateTime dt; dt = DateTime.Now; Console.WriteLine("{0}年{1}月{2}日", dt.Year, dt.Month, dt.Day); Console.WriteLine("{0}時{1}分", dt.Hour, dt.Minute); } 日付と時間を扱うDateTime構造体 現在の時刻を取得する静的プロパティDateTime.Now DateTime構造体は,年,月,日,時,分,秒,曜日等など,様々なプロパティを持っている. →詳しくはDateTimeをキーワード検索 問題: GUIプログラムではDateTime構造体をどこで宣言し,どこで現在時刻を取得するか?
DateTimeのインスタンスを宣言する場所 namespace Matsushima using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; namespace Koushu80 { /// <summary> /// Form1 の概要の説明です。 /// </summary> public class Form1 : System.Windows.Forms.Form /// 必要なデザイナ変数です。 private System.ComponentModel.Container components = null; private System.Windows.Forms.Label labelDate; private System.Windows.Forms.Label labelTime; private System.Windows.Forms.Button buttonFinish; private DateTime dt; public Form1() // // Windows フォーム デザイナ サポートに必要です。 InitializeComponent(); // TODO: InitializeComponent 呼び出しの後に、コンス・・ DateTime dt; dt = DateTime.Now; labelDate.Text = string.Format("西暦{0}年{1}月{2}日", dt.Year, dt.Month, dt.Day); labelTime.Text = string.Format("{0}時{1}分", dt.Hour, dt.Minute); } /// <summary> /// 使用されているリソースに後処理を実行します。 /// </summary> protected override void Dispose( bool disposing ) { if( disposing ) if (components != null) components.Dispose(); } base.Dispose( disposing ); Windows Form Designer generated code /// アプリケーションのメイン エントリ ポイントです。 [STAThread] static void Main() DateTime dt; dt = DateTime.Now; Application.Run(new Form1()); 正解その1 DateTimeのインスタンスdtをForm1のメンバとして宣言する →Form1内からアクセス可能 正解その2 インスタンスdtがForm1コンストラクタメソッド内のローカル変数でも良いならこれでOK (この例ではローカル変数でも問題ない) 不正解 インスタンス(変数)dtはMain()メソッド内のローカル変数になるため,イベントハンドラ等からアクセスできない 現在時刻を取得して,Labelコントロールに設定
アプリケーションの終了 buttonFinish これをクリックしたら,アプリケーションが終了する → クリックイベントのイベントハンドラ内で終了処理 イベントハンドラ private void buttonFinish_Click(object sender, System.EventArgs e) { Application.Exit(); } 静的メソッドApplication.Exit()はアプリケーションを終了させる