none
親フォームのインスタンスを比較するには RRS feed

  • 質問

  • 複数のフォーム 例えば form親, form子 ,form孫があり form子とform孫は他からも起動させることがあり form子やform孫が起動したときに親がどちらか判断するために

    form子とform孫に Oya as form と 親が何かを代入する変数を宣言しておき

    __________________________

    Public Class Form親
        Public oya As Form

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Dim fm As Form子 = New Form子
            fm.oya = Me
            fm.Show()
        End Sub
    End Class

    __________________________

    Public Class Form子
        Public oya As Form

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Dim fm As Form孫 = New Form孫
            fm.oya = Me
            fm.Show()
        End Sub
    End Class

    __________________________

    として form子やform孫を起動させています

    そして form子のほうで

    _________________________________

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Select Case True
                Case oya Is Form親
                    MsgBox("form親")
            End Select
        End Sub

    __________________________________

    form孫のほうで

    __________________________________

        Private Sub Button1_Click(ByVal sender As System.Object,  ByVal e As System.EventArgs) Handles Button1.Click
            Select Case True
                Case oya Is Form子
                    MsgBox("form子")
            End Select
        End Sub

    __________________________________

    としたときに form親からform子を起動させたときはTrueになりMsgboxが 思うように出るんですが
    なぜか form子からform孫を起動させたときには Falseになってしまいます

            Select Case oya.Name
                Case Is = Form子.Name
                    MsgBox("form子")
            End Select

    このように名前で比較するとtrueになるんですが いったいなにが駄目なんでしょう?

    2006年7月29日 1:22

回答

  •  じゃんぬねっと さんからの引用

    '型' なのか、'自分で管理すべきインスタンス' なのか、
    それとも、VB2005 側で加わった '暗黙的にインスタンス化されたシングルトン' なのか、
    区別がつきにくいので使わない方が絶対に良いでしょうね。

    # 以前、Blog で暗黙のインスタンス化を大反対したことがあります。

    じゃんぬねっとさん 最後までありがとうございました

    そうします

    ややこしいですね・・・ 便利にしようとしてるんでしょうけど(素人の私にとっては お陰で間違ったコードでも無事に動いている部分は多々あるはずですが・・)

     

    どうもありがとうございました

    2006年7月30日 7:06

すべての返信

  • かずboo さん、こんにちは。

     かずboo さんからの引用
    なぜか form子からform孫を起動させたときには Falseになってしまいます

    まずは、MessageBox を出力するプロシージャで、ブレーク ポイントを設定して、
    'oya' には、実際何が格納されているのか、式ウォッチや GetType メソッドを使って検証されてはいかがでしょうか?

    # それと、このご質問は件名にある "親フォームを比較するSelect Caseについて" とは、直接関係ないですよね?

    2006年7月29日 2:48
  •  じゃんぬねっと さんからの引用

     

    まずは、MessageBox を出力するプロシージャで、ブレーク ポイントを設定して、
    'oya' には、実際何が格納されているのか、式ウォッチや GetType メソッドを使って検証されてはいかがでしょうか?

    # それと、このご質問は件名にある "親フォームを比較するSelect Caseについて" とは、直接関係ないですよね?

    ウォッチとGetTypeやってみました

    どちらとも form孫の Oyaの型は ”試験用.Form子”(プロジェクトの名前が{試験用}です)と正しく出ました

    もちろん form子の Oyaは ”試験用.Form親”でした

    試しに 親から孫を起動させるのもやってみましたが こちらはうまくいきました

     

    全く同じ内容の構文だと思うのですが 何が違うんでしょう

    あと 何を見れば良いですか?

     

    2006年7月29日 4:13
  • Form親, Form子, Form孫に継承関係が有るんじゃないですか?
    2006年7月29日 6:24
  • Case TypeOf oya Is Form親
    もしくは
    Case oya.GetType() Is GetType(Form親)

    ではないでしょうか?
    (両者は同じ意味ではありません。中さんの件は、VB では TypeOf した場合ですよね...)

    そもそも最初に書かれたコードは「oya Is 型」となっていますので、コンパイルエラーになりませんか?

    2006年7月29日 6:57
  •  TH01 さんからの引用
    そもそも最初に書かれたコードは「oya Is 型」となっていますので、コンパイルエラーになりませんか?

    型と同名のアクセス可能な変数がある場合は、コンパイル エラーにはなりませんね。


    Dim Form子 As New Form子()

    Select Case True
        Me.oya Is Form子
            MessageBox.Show("Form 子")
    End Select

     

    当然、インスタンスは同一ではないので、Case の評価は False を返します。
    まさか、今回の原因はコレ!?

    2006年7月29日 7:48
  •  じゃんぬねっと さんからの引用

    型と同名のアクセス可能な変数がある場合は、コンパイル エラーにはなりませんね。

    それはそうですが...(^^;

     じゃんぬねっと さんからの引用

    まさか、今回の原因はコレ!?

    最初のコードに
    Dim fm As Form子 = New Form子
    と書かれていたので、その線は無いと思っていました。
    けどそうかも...

    2006年7月29日 8:12
  • じゃんぬねっと さん
    中博俊 さん
    TH01さん

    たくさんの御指導ありがとうございます

    型と同名の変数はないのですが というかないと思うのですが一応これを確認するために新たにフォームとボタンが一つだけのプロジェクトを作って テストしておりますので たぶん見逃してはいないと思います 自信はないですが

    普通なら 書いていたコードで うまくいくはずなんでしょうか

    いろいろやってみて 下のようなコードにして見たのですが これだとうまくいきました

            Dim oyaTy As Type = oya.GetType
            Dim myTy As Type = Formテスト.GetType
            Select Case True
                Case oyaTy Is myTy
                    MsgBox(oyaTy.ToString & "=" & myTy.ToString)

            End Select

    このように GetTypeしてから 比較すれば Trueが返ってきました

    これが正解なんでしょうか?

     

    ところで じゃんぬねっとさん

    # それと、このご質問は件名にある "親フォームを比較するSelect Caseについて" とは、直接関係ないですよね?

    ここは どう書けば良かったんでしょうか 「親フォームを比較するには」になるのかな Select Caseは関係ない という意味ですか? もしタイトルを書き換えるとすれば どこを触ればいいんでしょう

     

     

    2006年7月29日 9:27
  • かず boo さん、こんにちは。

     かずboo さんからの引用
    型と同名の変数はないのですが というかないと思うのですが一応これを確認するために新たにフォームとボタンが一つだけのプロジェクトを作って テストしておりますので たぶん見逃してはいないと思います 自信はないですが

    だとすれば、先の型を比較していないコードは、
    ご指摘がすでにあったように、コンパイル エラーになると思います。

    このように GetTypeしてから 比較すれば Trueが返ってきましたこれが正解なんでしょうか?

    結局のところ、どちらをご所望なのでしょうか?
    A が B と同一のインスタンスであることと、A の型が B の型と同一であることは全然意味が違いますよね。

    型を見たいのであれば、TypeOf [検証対象のインスタンス] Is [型名] が正解です。

    ここは どう書けば良かったんでしょうか 「親フォームを比較するには」になるのかな Select Caseは関係ない という意味ですか? もしタイトルを書き換えるとすれば どこを触ればいいんでしょう

    ごめんなさい、意味がわかりにくかったですね。

    仰るとおりになるかと思います。
    Select Case "だから" うまくいかないのであれば、Select Case という文言は必要ですが、今回はそういうわけではないですよね?

    タイトルは [編集] を選択することで、普通に変えられます。

    2006年7月29日 10:47
  • じゃんぬねっとさん ありがとうございます

     

    実際のところは 型で確認できれば 現在作っているアプリケーション上では問題ないのですが 自分の知識を付けたいのと 思うように作動してくれない原因が知りたいのとです 

     

    もう一度 その為だけのアプリケーションを作って試したところ

    今度は 孫から子を確認する事ができました

    実は ここに投稿しているコードのform親とかform子とかは 見易いように

    書き換えておりまして 実際は form1であったりformテストであったりでしたので

    再度、上に書いている通りの名前を 使ったアプリケーションを作り直したところ

    思うように動きました

     

    という事は 御指摘頂いている 型と同名の変数がある という事ですか 上のコードの場合 「Form子」という

    変数がどこかにあるという事になるんでしょうか と思い クイック検索で「現在のプロジェクト」として「form子」を

    検索してみたのですが 変数にはなっていないような・・

     

    でも 試しに

    だめだった方のプロジェクトのform孫で単にnewを付けずに

    form子.show()とすると 子が起動しましたが

    新しいうまくいった方で 同じことをしても子は起動しませんでした

    という事は 御指摘いただいている通り form子には 既に別のインスタンスが入り込んでいたという考え方でいいんでしょうか? もしそうだとしたら どんなことをしたときに 宣言していないform子にインスタンスが入ってしまうんでしょう?

     

    そして もうひとつ 今度はform子をスタートアップフォームにして そこから孫を起動させ同じことをすると 今度は子は起動しませんでした

    ということは 親が起動しているときに 子のインスタンスが出来てしまっているという考え方でよかったですか

     

    2006年7月29日 12:33
  •  かずboo さんからの引用
    という事は 御指摘頂いている 型と同名の変数がある という事ですか 上のコードの場合 「Form子」という
    変数がどこかにあるという事になるんでしょうか と思い クイック検索で「現在のプロジェクト」として「form子」を
    検索してみたのですが 変数にはなっていないような・・

    VS2005 の新機能が関係していました。
    これは、フォームクラス名をインスタンスとして扱うコードを書くと、コンパイラによってインスタンスに解釈されるものです。
    具体的には、My.Forms(実際は My.MyProject.Forms)に動的に作成される Form2 というプロパティに置き換えられます。

    If oya Is Form親 Then
    ↓コンパイル結果
    If oya Is My.MyProject.Forms.Form親 Then

    このプロパティは、初回の参照時にフォームインスタンスを作成してそれを戻し、それ以降の参照時には同じものが戻されるようになっています。
    このことは、「Visual Basic 2005 の My 機能の検証」<http://www.microsoft.com/japan/msdn/vs05/vbasic/vbmy.aspx>の「動的に生成されるクラス」の「My.Forms」に書かれていました。

    自分で New するフォームインスタンスは、もちろん毎回新しいものなのでいくつも開くことができますが、上述の暗黙のインスタンスは常に同じものなので、すでに Show されていればもう一度 Show しても何も起こりません。

    [言い訳]
    実は最初に返信する際に、これが頭をよぎったので実験していたのですが、そのときはちゃんとエラーになったので、関係ないやと思ってしまいました。後からこの点だけを新規作成したプロジェクトで試験したので、たぶん Form2 を追加し忘れているのに Is Form2 がエラーになったのを勘違いしたのだろうと思います。(^^;
    VB はややこしい。

    2006年7月29日 16:03
  •  TH01 さんからの引用

    VS2005 の新機能が関係していました。
    これは、フォームクラス名をインスタンスとして扱うコードを書くと、コンパイラによってインスタンスに解釈されるものです。
    具体的には、My.Forms(実際は My.MyProject.Forms)に動的に作成される Form2 というプロパティに置き換えられます。

    If oya Is Form親 Then
    ↓コンパイル結果
    If oya Is My.MyProject.Forms.Form親 Then

    このプロパティは、初回の参照時にフォームインスタンスを作成してそれを戻し、それ以降の参照時には同じものが戻されるようになっています。
    このことは、「Visual Basic 2005 の My 機能の検証」<http://www.microsoft.com/japan/msdn/vs05/vbasic/vbmy.aspx>の「動的に生成されるクラス」の「My.Forms」に書かれていました。

    [言い訳]
    実は最初に返信する際に、これが頭をよぎったので実験していたのですが、そのときはちゃんとエラーになったので、関係ないやと思ってしまいました。後からこの点だけを新規作成したプロジェクトで試験したので、たぶん Form2 を追加し忘れているのに Is Form2 がエラーになったのを勘違いしたのだろうと思います。(^^;
    VB はややこしい。

    TH01 さん 最後まで検証くださって ありがとうございます

     

    本当にややこしいです

    ということは ここでは 「クラス名」=フォームなので インスタンスで比較するコードを書くと (oya is Form子

    いつおくしくなるか分からない=使わないほうがいい

    と理解して良いですか?(今回作成中のアプリは型で判断で充分なのですが)

    2006年7月29日 22:57
  • なるほど、VB8 (VB2005) ならではの落とし穴でしたか。(これは気付きませんでした)

     かずboo さんからの引用
    いつおくしくなるか分からない=使わないほうがいい
    と理解して良いですか?(今回作成中のアプリは型で判断で充分なのですが)

    '型' なのか、'自分で管理すべきインスタンス' なのか、
    それとも、VB2005 側で加わった '暗黙的にインスタンス化されたシングルトン' なのか、
    区別がつきにくいので使わない方が絶対に良いでしょうね。

    # 以前、Blog で暗黙のインスタンス化を大反対したことがあります。

    2006年7月30日 6:53
  •  じゃんぬねっと さんからの引用

    '型' なのか、'自分で管理すべきインスタンス' なのか、
    それとも、VB2005 側で加わった '暗黙的にインスタンス化されたシングルトン' なのか、
    区別がつきにくいので使わない方が絶対に良いでしょうね。

    # 以前、Blog で暗黙のインスタンス化を大反対したことがあります。

    じゃんぬねっとさん 最後までありがとうございました

    そうします

    ややこしいですね・・・ 便利にしようとしてるんでしょうけど(素人の私にとっては お陰で間違ったコードでも無事に動いている部分は多々あるはずですが・・)

     

    どうもありがとうございました

    2006年7月30日 7:06
  • 終わりましたが...(^^;

     かずboo さんからの引用
    いつおくしくなるか分からない=使わないほうがいい
    と理解して良いですか?

    暗黙のインスタンスは常に同じものが戻されるので、「いつおかしくなるか分からない」ということはないと思います。
    フォームインスタンスを期待する個所で、自身で New したインスタンスを用いたり、暗黙のインスタンスを用いたりすれば、必然的に期待通りの結果にはならないと...。

    じゃんぬさんの文面に勝手に括弧書きさせていただくと
    「...区別がつきにくいので(暗黙のフォームインスタンスは)使わない方が絶対に良いでしょうね」
    となりますが、使わないつもりでも間違えて使っちゃってハマりそうです...(^^;
    かずboo さんは、新機能として追加された過ちを犯しやすい仕様の犠牲者第1号かも。

     かずboo さんからの引用
    (今回作成中のアプリは型で判断で充分なのですが)

    今回のような場合、通常は型で判定する場面の方が多いと、私は思います(アプリ仕様次第ですが)。


    今回の件、普段 C# を使用している人がちょっと VB での仕事の手伝いをした時に、フォームの型に対して TypeOf を忘れて Is してハマっちゃうという場面が目に浮かびます。(^^;
    なお、投稿する際はいつもフォーラムの分類に違和感を感じていたのですが、今回の件は「VB フォーラム」ではなく「共通フォーラム」がぴったりな気がしました。

    2006年7月31日 3:34
  • TH01さん ありがとうございます

     TH01 さんからの引用

    暗黙のインスタンスは常に同じものが戻されるので、「いつおかしくなるか分からない」ということはないと思います。
    フォームインスタンスを期待する個所で、自身で New したインスタンスを用いたり、暗黙のインスタンスを用いたりすれば、必然的に期待通りの結果にはならないと...。

     TH01 さんからの引用

    じゃんぬさんの文面に勝手に括弧書きさせていただくと
    「...区別がつきにくいので(暗黙のフォームインスタンスは)使わない方が絶対に良いでしょうね」
    となりますが、使わないつもりでも間違えて使っちゃってハマりそうです...(^^;
    かずboo さんは、新機能として追加された過ちを犯しやすい仕様の犠牲者第1号かも。

    今回のような場合、通常は型で判定する場面の方が多いと、私は思います(アプリ仕様次第ですが)。

    結局、解決したものの どこでインスタンスが入ってしまったのかは 検証できてませんし

    順番にコードをコメントアウトしながら検証するつもりですが

    もっと知識がついてからでないと 使い切れないかな?

     TH01 さんからの引用


    今回の件、普段 C# を使用している人がちょっと VB での仕事の手伝いをした時に、フォームの型に対して TypeOf を忘れて Is してハマっちゃうという場面が目に浮かびます。(^^;
    なお、投稿する際はいつもフォーラムの分類に違和感を感じていたのですが、今回の件は「VB フォーラム」ではなく「共通フォーラム」がぴったりな気がしました。

    Cは全然分からないんですが いろいろな掲示板など見てると 勝手に型変換とかしないんですね

    これも私にはまだ無理かな

     

    いろいろ ありがとうございました


     

    2006年7月31日 12:20