連載:アップグレード・ウィザードに学ぶVB 6→VB 2005

第3回 ココが違う! VB 6と.NETのコントロール・コレクション

グレープシティ株式会社 八巻 雄哉
2007/03/16
Page1 Page2

動的に追加したコントロールを削除する部分

 [削除]ボタンが押されると、TextBoxコントロールを削除します。VB 6のControlsコレクションに用意されているRemoveメソッドでは、パラメータに削除したいコントロールの名前を文字列で指定しました。

Me.Controls.Remove "Text1"
「Text1」の削除(リスト1より抜粋)

 VB 2005のControlCollectionクラスに用意されているRemoveメソッドはパラメータに削除したいコントロールのオブジェクトを指定するようになっています。削除したいコントロールの名前を文字列で指定して削除するには、RemoveByKeyメソッドを使用します。よって変換されたコードは、以下のように修正しなければなりません。

' Text1をFrameコントロールから削除します。
Me.Frame1.Controls.RemoveByKey("TextBox1") ' 名前で指定する場合。
'Me.Frame1.Controls.Remove(TextBoxObject) ' オブジェクトで指定する場合。
リスト4 VB 2005で動的に追加したコントロールを削除する場合

 ちなみに、アップグレード・ウィザードで変換されたコードであるRemoveAtメソッドは、Controlsコレクションでのインデックス番号を指定して削除するメソッドです。

 なお、VB 6では動的に追加したコントロールだけしか削除することができませんでしたが、VB 2005ではフォームの設計時に配置したコントロールも、動的に追加したコントロールもまったく同等ですので、どちらも削除することが可能となっています。

フォーム上のすべてのボタンの背景色を白に設定する部分

 続いては、[全部白いボタン]ボタンが押されたときに、すべてのボタンの背景を白に設定する部分です。Controlsコレクションから取り出したコントロールがボタンかどうかをチェックする処理が、まずはポイントとなります。この部分では、アップグレード・ウィザードによって「TypeOfに新しい動作が指定されています。」という警告文が追加されています。

 VB 6でオブジェクト型を比較するために使用していたTypeOfキーワードは、VB 2005でもTypeOf演算子として存在します。しかしながら、その動作にはいくつか異なる点がありますので、まずはその違いについて説明します。

■VB 6のTypeOfキーワードとVB 2005のTypeOf演算子の違い

  • If 〜 Then 〜 Elseステートメントでなくとも使える

 これはほとんど問題にならないと思いますが、VB 6ではIf 〜 Then 〜 Elseステートメント内で使うキーワードであったのに対し、VB 2005ではどこでも使用することができます。

  • VB 2005では、VB 6のユーザー定義型に相当する構造体は評価できない

 VB 6では、複数のデータ型を組み合わせた独自のデータ型である「ユーザー定義型」を作ることができます。ユーザー定義型はオブジェクト型として扱われるため、TypeOfキーワードを使って評価することができました。

' VB 6のユーザー定義型。
Private Type MyType
  a As Integer
End Type

Private Sub Form_Load()
  Dim m As MyType

  ' ユーザー定義型もTypeOfキーワードを使用可能。
  If TypeOf m Is MyType Then
    MsgBox "MyType"
  End If

End Sub
リスト5 VB 6でユーザー定義型の型を評価する場合

 一方、VB 2005でユーザー定義型に相当するものは「構造体」です(ユーザー定義型はアップグレード・ウィザードで構造体に変換されます)。

 構造体はオブジェクト型(参照型)ではなく値型であるため、TypeOf演算子を使って評価することはできません。構造体の場合には、GetTypeメソッドとGetType演算子を使い、その型に関する情報を含んだTypeオブジェクトを取得して比較します。

' VB 2005の構造体。
Private Structure MyType
    Dim a As Integer
End Structure

Private Sub Form1_Load(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles MyBase.Load
  Dim m As MyType

  ' GetTypeメソッドとGetType演算子で構造体の型を評価する。
  If m.GetType Is GetType(MyType) Then
    MsgBox("MyType")
  End If

End Sub
リスト6 VB 2005で構造体の型を評価する場合

 今回の場合、TypeOf演算子で評価されるのはフォーム上のコントロールとなりますので、この動作の違いは問題になりません。

  • 派生クラスのオブジェクトも結果はTrueが返される

 VB 6では、「継承」はインターフェイスの実装によってのみ可能でしたが、VB 2005では本当の意味での継承がサポートされ、クラスはほかのクラスを継承することができます。これにより「互換性のある型」というものが存在します。

 VB 2005のTypeOf演算子は、厳密には同じ型であるかどうかを評価しているのではなく互換性のある型かどうかを評価しています。このため、継承先のクラス(派生クラス)のオブジェクトは継承元のクラスのオブジェクトと互換性があると判断されます。

' Buttonクラスを継承したMyButtonクラス。
Public Class MyButton
  Inherits Button
End Class

Private Sub Form1_Load(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles MyBase.Load

  Dim inheritsButton As New MyButton

  ' TypeOfではMyButtonクラスのオブジェクトはButtonクラスの
  ' オブジェクトと型に互換性があると判断される。
  If TypeOf inheritsButton Is Button Then
    MsgBox("このオブジェクトは互換性があります。")
  End If

  ' GetTypeでは型情報であるTypeオブジェクトを比較するため、
  ' 異なる型であると評価できる。
  If inheritsButton.GetType Is GetType(Button) Then
    MsgBox("異なるTypeオブジェクトです。")
  End If

End Sub
リスト7 派生クラスのオブジェクトの型を評価する際のTypeOfとGetTypeの違い

 ここまでVB 6とVB 2005のTypeOf演算子の違いを説明してきましたが、今回のサンプル・プロジェクトの場合には、そのままTypeOf演算子を使っても動作が異なることはないということが分かりました。

■VB 2005ですべてのコントロールを取得

 しかしながら、実際に実行してみると実はこれ以外の部分でVB 6とは動作が決定的に異なる部分があることが分かります。ここまでの修正を反映して実行し、[全部白いボタン]ボタンを押したところです。


図3 ここまでの修正を反映して実行した画面(VB 2005アプリケーション)

 フォーム上に直接配置されているボタンの背景色は白に変更されるものの、GroupBoxコントロール(画面上の表記はFrameコントロール)上に配置されたボタンの背景色は白に変更されません。これは、「コントロールを動的に追加する部分」で説明した、フォーム上に配置されたコントロールの親子関係におけるVB 6とVB 2005の違いが影響しています。

 VB 2005ですべてのコントロールを取得するためには、FormオブジェクトのControlsプロパティから各コントロールを取得し、さらにそれらのコントロールのControlsプロパティを取得して子コントロールが存在するかどうか確認するという具合に、階層をたどってコントロールを取得する必要があります。

 ここでは、フォーム上のすべてのコントロールを取得するMyControls関数を作成してみましょう。このMyControls関数は、GetAllControlsプロシージャを呼び出すことで、作成したフォーム上のすべてのコントロールを持つコレクションを返します。GetAllControlsプロシージャでは、コントロールのControlsプロパティから子コントロールが存在するかどうかを確認し、子コントロールが存在する場合にはGetAllControlsプロシージャを再帰呼び出しする方法ですべての階層のコントロールを取得します。

 この方法を実装したコードがリスト8になります。

Private Sub CommandWhite_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles CommandWhite.Click

  ' MyControls関数からフォーム上のすべてのコントロールを
  ' 含むコレクションを受け取ります。
  For Each currentControl As Control In MyControls()

    ' Buttonコントロールのみ背景色を白に設定します。
    If currentControl.GetType Is GetType(Button) Then
      currentControl.BackColor = Color.White
    End If
  Next

End Sub

' フォーム上のすべてのコントロールを含むListオブジェクトを
' 返すMyControls関数。
Function MyControls() As System.Collections.Generic.List(Of Control)

  Dim controlList As New System.Collections.Generic.List(Of Control)

  GetAllControls(Me, controlList)
  Return controlList

End Function

Sub GetAllControls(ByVal parentControl As Control, ByVal controlList As System.Collections.Generic.List(Of Control))

  For Each currentControl As Control In parentControl.Controls

    controlList.Add(currentControl)

    ' 子を持つコントロールの場合、GetAllControlsプロシージャを
    ' 再帰的に呼び出すことで子コントロールを取得します。
    If currentControl.Controls.Count > 0 Then
      GetAllControls(currentControl, controlList)
    End If

  Next
End Sub
リスト8 VB 2005でフォーム上のすべてのボタンの背景色を白に設定する場合

 上記のコードを適用してサンプル・プロジェクトを実行すると、GroupBoxコントロール上に配置されているボタンの背景色も白に設定されることを確認できます。

 以上、今回はControlsコレクションに関するコードの変換を行いました。VB 2005ではフォームとコントロールの関係が若干異なるので最初は少し戸惑うかもしれませんが、慣れてしまえばVB 2005の方がずっと分かりやすい構造になっていると感じることができるでしょう。では、次回をお楽しみに。End of Article


 INDEX
  アップグレード・ウィザードに学ぶVB 6→VB 2005
  第3回 ココが違う! VB 6と.NETのコントロール・コレクション
    1.コントロールを動的に追加
  2.追加したコントロールを削除/すべてのボタンの背景色を白に

インデックス・ページヘ  「アップグレード・ウィザードに学ぶVB 6→VB 2005」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)
- PR -

注目のテーマ

業務アプリInsider 記事ランキング

本日 月間
ソリューションFLASH