羊の皮を着た狼 VB.NE | |
|
1、Form2が表示できない。(VB2003)
(Q) プロジェクトでフォームの追加(F)を押してForm2を追加したけれど、
実行してもForm2が表示されない。
(A) あなたが追加したのはForm2のクラス(型)だけなんです、インスタンス(実体)は 追加していないんです。 インスタンスを作成するには次のようにします。 VB.NET コード Form1
Public Class Form1
Form1もForm2もクラスなのです、クラスはいわば単なる型なのです、
実際に見ようとしているものはクラスではなくオブジェクトなのです。 オブジェクトはNewステートメントを使ってクラスから作成されます。 クラスから作られたオブジェクトはインスタンスとも呼ばれます。 (注) Dim F2 As New Form2 はDim F2 As Form2 とF2 = New Form2 の宣言と代入を一度に行っています。 2、Form2からForm1を参照したい。
(Q)Form2からForm1のTextBox1に書き込みたいのですが、 Form1.TextBox1.Text = "Hello World!"では書き込めません。 (A)Form1もクラス(型)なんです、インスタンス(実体)で無いので参照が出来ません。 次のサンプルは、Form1上のテキストボックスに、「Hello World!」をForm2上にボタンを押すことにより 書き込んでいます。
Moduleのコード Form2からForm1を参照する
Module Module1
Form1側のコード Form2からForm1を参照する
Public Class Form1
Form2側のコード Form2からForm1を参照する
Public Class Form2
共通モジュールでForm1クラスF1をグローバルに宣言し、
Form1のインスタンスは" Me " で参照できます、Form1の起動時にF1にForm1のインスタンスを代入します。
(注意)
上記の参照方法はいちばん簡単な参照方法です、ただしプログラマの中にはモジュールの宣言を グローバルで行うことに抵抗を感じる人も居ます。 共通モジュールを使わない方法も下のページで解説しています。 Form1、Form2相互参照
3、Form1のインスタンスはどこで作られるの。
(Q)Form1もクラスならForm1のインスタンスはどこで作られるのですか?
(A)Form1は基本クラスです基本クラスは" Windows フォーム デザイナで生成されたコード "の中で作成されます。 "MyBase.New()"この部分です、そのインスタンスは"Me"です。
4、Form2からForm1をアンロードする。
(Q)Form2から呼び出し元のForm1をアンロードしたいのですが。
(A)Form1.Closeを行います。ただしForm1がクローズされると、呼び出されたFormは全てクローズされてしまいます。 木の枝を切っていて、自分の乗っている木の枝を切って落ちた人が居ましたが、あれと同じです。 このような場合は"Form1.Hide"を使用しましょう。これはForm1を非表示にします。 Form1を非表示にしたまま、Form2をクローズするとForm1を表示する方法がなくなります。 Form2を非表示にする場合は必ずForm1を表示しましょう。 Form1を表示する方法は、"Form1.Show()"ですが、Form2から行う場合は上の「Form2からForm1を参照したい」を 参照してください。
(注意)
このFormに関する記事はVB2003をベースに書かれています。
VB2005になってFormの仕様が大きく変わり、又元のVB6の様にエディターで置くだけで、 どのフォームからも参照できる様になりました。 これはデフォルトインスタンスを言って、エディターが自動的にインスタンスを作成します。 つまりForm2をエディターで置いてForm1上でForm2.Visivle = True とすると、Form2が表示されます。 又Form1上のテキストボックスTextBox1に「Hello!」と書き込むにはForm1.TextBox1.Text="Hello!" とすれば良いのです。 何のことは有りません、VB6と同じになったのです。 VB.NETに慣れたFormも単純なクラスであると理解している人には、Formは複雑です。 VB6から移行した人には、極めて単純です。 もちろん今までの方法も使用できます、念の為に。 ただしこれには賛否両論があります、私は中立です。 上の質問の『Form2が表示出来ない』の回答は『VB2005に移行しなさい』という事になります。
5、テキストボックスやコマンドボタンの配列を作りたい。
(Q)VB6ではText1をフォームの上に置いてそれをコピーすることでコントロールの配列を作りましたが、
VB.NETの場合TextBox1をコピーして貼り付けるとTextBox2になり配列が出来ないのですが。 (A)VB.NETではコントロールの配列は作ることが出来ません。オブジェクトの配列を使います。
・下に4つのボタンをフォームの上に作る例を示します。
コマンドボタンの配列を作成するサンプル。
Public Class Form1 ボタンを置く
Dim MyButton(4) As Buttonでボタンオブジェクトを5つ用意します。 MyButton(n) = New Button でインスタンスを作成しています。 ・MyButton(n).Parent = Me MeはForm1ですこれを書かないとMyButton(n)は表示されません。 「フォームを親としてその上に置くよ」という意味です。 GroupBoxを使う場合はMyButton(n).Parent = GroupBox1となります。 これは又 ・Controls.Add(MyButton(n))でもOKです。 イベントハンドラの設定
「ハンドラ」と操作する人と言うような意味でしょうか、ここではクリックイベントを
引き受けるサブルーチンを指します。 AddHandler MyButton(n).Click, AddressOf Button_click は MyButton(n)がクリックされた時、Button_clickのSubに飛びなさいということで、 Button_clicKはイベントハンドラーと呼ばれます。 「AddHandlerによりMyButton_clickイベントのイベントハンドラを設定する」といいます。 イベントの名前「Button_click」はどんな名前でも構いません。 Tagに配列の番号を入れてイベントハンドラに渡す。
「Tag = n」はButton_clickの中でどのボタンが押されたか判断するためにボタンの配列の番号を
Tagに設定しています。
この方法はチョッとトリッキーで一般的ではないかも知れません。 実はボタンが押された時にどのボタンが押されたかは、 Button_clickiイベントの引数に渡ってきます。 従ってTagにIndexを埋め込む方法の他に、渡って来たMyButtonの名前でどのボタンのイベントなのか 判断する方法も有りこの方が一般的かもしれません。 その場合は.Name = strName & i.ToStringのようにボタンの名前を設定します。 イベントハンドラの作成
「Private Sub Button_click」のイベントハンドラは自分で作成します。
イベントハンドラの引数は決まりが有ります、手で打ち込むのとが面倒な場合は、 その辺から適当にコピーするか、フォームの上にボタンを一つ置いてそれをクリックして出来る イベントハンドラの名前をを変更し、その後置いたボタンを削除してもいいでしょう。 イベントハンドラの中でイベント発生元のボタンを取得
Sub Button_clickイベントの中では引数senderで押されたMyButtonのプロパティが参照できます。
たとえばMyButton(n).Tagはsender.Tagで参照できます。 タグにMyButtonのインデックスを埋め込んだ場合は、senderからそのTagを取得します。 名前で取得する場合は番号の部分を抜き出します、コードのサンプルでは名前から抜き出す部分は コメントアウトして有ります。 この部分はちょっと複雑になっていますが、名前がButton1 Button2 ...となっている為で、 名前を『1 2 3 ..』というように番号だけにしておけば、 ・Dim index As Integer = CInt(MyButton.Name) だけになります。 事前バインディングと実行時バインディング
イベントハンドラの第1引数のsenderですがsender.としてもsenderのプロパティ候補は
IntelliSenceに表示されません、コード作成時はsenderに何が渡されるか判らないためです。 このように実行時に引渡しが決定される方式を実行時バインディング(遅延バインディング)と呼びます。 これに引き換え実行前に渡すものが決まっている場合を事前バインディングといいます。 コンパイルのオプション設定でOption Strict Onを設定した場合は、実行時バインディングは使えません。 事前バインディングの場合は「オブジェクト.」とするとIntelliSenceが候補を上げ コードの作成がが容易になります。 実行時バインディングの場合、対象となるオブジェクトに同じメソドなどが無い場合は、 ランタイムエラーとなり注意が必要です。 ・ Dim MyButton As Button = DirectCast(sender, Button) 上のコードはsenderをボタン型のオブジェクトに変換してMyButtonに入れています。 これにより事前バインディングが可能となり、コード作成時に『MyButton.』とすれば MyButtonのプロパティーが表示されます。 DirectCastの代わりCtype()を使うことも可能です 実際の処理
各ボタンの押された処理は、Select Case index 等で処理を行います。
(注意)
Private Sub Button_clickの中で宣言しているDim MyButton As Buttonはフォームレベルで宣言している、 Dim MyButton(4)とはたまたま名前が同じだけで 別物なので注意してください。
このコードはフォームの上に全くボタンを置か無い状態で書かれていますが、
あらかじめフォームの上にボタンなどを置いてそれを配列にする方法も有ります。 又全く配列を使わずにあたかも配列の様にコントロールを扱う方法も有ります。 こちらをご覧下さい。 VB.NET コントロールの配列をインデクサで処理する 6、コモン言語ランタイム(CLR)
(Q)コモン言語ランタイムって何でしょうか、又何が変わるのでしょうか?
(A)複数の言語を同じランタイム (実行エンジン)で動かそうとするものなのです。 つまりVB.NETで書いても、C#でも、J#でも更に驚いたことにLinuxまでが同じエンジンの上で動くということなのです。 今まで異種言語で最も問題になるのはメモリーの管理でした、CLRはそれらを同じエンジンで行います。 又言語ごとの異なっていたデーター型も統一されたのです。それに伴って今までVBで使われていたIntegerは 2バイトから4バイトに変更されました。 7、コモン言語ランタイムによって何が変わるの?
(Q)コモンタイム言語ライブラリーで何が変わるのでしょうか?
(A)プログラムはインストーラーによってインストールする必要はなくなりました。 プログラムをフォルダーに置いて実行するだけです。 ランタイムライブラリーを入れ替えたら、今まで動いていた 他のプログラムが動かなくなったということも有りません。 プログラムのインストールにレジストリーを使いません。 一方プログラムの開発者から見ますと、VB.NETとC#は非常に近い言語となりました。 もしかしたら参考書は1冊でよいかも知れません。 8、個々のプログラムの情報はメタデーターに。
(Q)個別の言語のの違いや、情報はどこに書き込まれるのですか?
(A)プログラムそのもの情報(メタデーターと言う)はそのファイルそのものの中に書き込まれます。 9、オブジェクト
(Q)オブジェクトとは何でしょうか?
(A)TextBoxやButton、Label、PictureBox等は全てオブジェクトと呼ばれます。 もちろんFormもオブジェクトです。 驚いたことに、Integer等のデーター型もオブジェクトなのです。
コモンイベント・プロシジャーサンプル
Private Sub obj_MouseEnter(ByVal sender As Object, _
VB.NETのフォームデザイナーでTextBox、Button、 CheckBox、RadioButton、PictureBox、Label
をフォームの上に置き次のコードを書きます。 このコードはマウスがTextboxやButtonの上を通過する度にそのオブジェクトの名前を TextBoxに書き込みます。 Private Sub obj_MouseEnterはコモンイベント・プロシジャーと呼ばれるもので、 Handle以下のイベントを一括で処理します。 .MouseEnterはマウスがそのオブジェクトの上を通過する時に発生します。 sender.GetType.Nameでオブジェクトの名前を取得しています。 TextBoxやButtonで発生したイベントが Private Sub obj_MouseEnter にオブジェクトと言う形で送られて来たことがわかります。 追記: VB.NETの記事を読みに来た人にC#を勧めるのもおかしいのだが 特に最近C#にすべきであると感じているので書きます。 |