- PR -

インスタンスの上書き

投稿者投稿内容
KKK
大ベテラン
会議室デビュー日: 2003/10/10
投稿数: 119
投稿日時: 2004-04-21 09:18
こんにちは。
VB.NETで開発している者です。

現在、MDI構造にてメニュー(親フォーム)から子画面を開いています。
親フォームのメニュークリック時に、以下のように遅延バインディングを用いて、
子画面を開いています。

Dim clsAssembly As Reflection.Assembly
Dim clsStart As Object

clsAssembly = Reflection.Assembly.LoadFile("AAA.dll")
clsStart = clsAssembly.CreateInstance("AAA.clsStart")
Call clsStart.Open()

メニューを2回クリックすると、子画面が2つ開くわけですが、
ここで問題が起きます。
1つ目の画面のボタンを押すと、2つ目の画面のチェックとかが走ってしまいます。
インスタンスは別々に2つできているので、お互い影響はないと考えていたのですが、
考え方がなにか違うのでしょうか?
上の現象から考えると、インスタンスが上書きされているように思えるのですが....

何か原因が分かる方がいっらしゃいましたら、ぜひご指摘下さい。
お願いします。
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2004-04-21 11:55
諸農です。

まず、疑問なんですが、
引用:

Dim clsAssembly As Reflection.Assembly
Dim clsStart As Object

clsAssembly = Reflection.Assembly.LoadFile("AAA.dll")
clsStart = clsAssembly.CreateInstance("AAA.clsStart")
Call clsStart.Open()


VB.NETではObjectクラスにOpen()メソッドを持っているのでしょうか?
実インスタンスが持つメソッドに型情報を経由しないでアクセスできるのかしら?

引用:

1つ目の画面のボタンを押すと、2つ目の画面のチェックとかが走ってしまいます。
インスタンスは別々に2つできているので、お互い影響はないと考えていたのですが、
考え方がなにか違うのでしょうか?
上の現象から考えると、インスタンスが上書きされているように思えるのですが....



うむ。。1つ目の画面のボタン、2つ目の画面のチェック、が
何を指しているのかがわかりませんね。。

親コンテナのフォームとコンテナに格納される子供フォームを
それぞれプロジェクトを別にして作成して、子供フォームには
ボタンを一つ配置し、クリックイベントハンドラにフォームの
キャプション部を表示するコードを書いて試してみました。
言語はC#、環境はC#Builderです。

コード:
親フォームのメニュークリック

        private void menuItem2_Click(object sender, System.EventArgs e)
        {
           if (openFileDialog1.ShowDialog() == DialogResult.OK){
           Assembly asb = Assembly.LoadFile(openFileDialog1.FileName);
           Form fm = (Form)asb.CreateInstance("MDIAssChl.WinForm");
           fm.Text = DateTime.Now.ToString();
           fm.MdiParent = this;
           fm.Show();
           }
    }

子供フォームのボタンクリック
    private void button1_Click(object sender, System.EventArgs e)
    {
            MessageBox.Show(this.Text);
    }



ボタンクリック1回につき、メッセージボックスは1回しか表示されませんでした。


_________________
諸農和岳
Powered by Turbo Delphi & Microsoft Visual Studio 2005

十兵衛@わんくま同盟
http://blogs.wankuma.com/jubei/
KKK
大ベテラン
会議室デビュー日: 2003/10/10
投稿数: 119
投稿日時: 2004-04-21 13:08
返信ありがとうございます。

> VB.NETではObjectクラスにOpen()メソッドを持っているのでしょうか?
> 実インスタンスが持つメソッドに型情報を経由しないでアクセスできるのかしら?

親画面がexeで、子画面はdllにしてあります。
そして、子画面側にOpenメソッドを実装してあるので、動きます。

> うむ。。1つ目の画面のボタン、2つ目の画面のチェック、が
> 何を指しているのかがわかりませんね。。

説明不足でした。
たとえば、子画面側にOKボタンがあったとします。
このOKボタンは自身の画面のNULLチェックを行うとします。
すると、2つ画面を立ち上げた場合、1つ目の画面のOKを押すと、
2つ目の画面のNULLチェックが走ってしまうということです。
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2004-04-21 13:49
諸農です。

引用:

親画面がexeで、子画面はdllにしてあります。
そして、子画面側にOpenメソッドを実装してあるので、動きます。


なるほど。。。VBのことをぜんぜん知らないので。すみません。
VB.NETのCallというのが、Object型参照でもカスタマイズメソッドの
呼び出しを可能にしているということなんでしょうね。。
VB.NETって便利ですね。

で、ちなみに、Openメソッドの実装内容というのはどういったものなんでしょうか?
MDIフォームということなので、私のC#での認識で言えば、
MDIの子フォームは、自身のMdiParentプロパティにMDIのコンテナとなる
親フォームを指定する必要があるかと思います。
このあたりの制御も含めてOpenメソッド内に実装されていると考えても
いいのでしょうか?そして、生成された子フォームのインスタンスを
Show()する必要もあるかと思いますが、これもOpenの中で行われていると。

引用:

たとえば、子画面側にOKボタンがあったとします。
このOKボタンは自身の画面のNULLチェックを行うとします。
すると、2つ画面を立ち上げた場合、1つ目の画面のOKを押すと、
2つ目の画面のNULLチェックが走ってしまうということです。



2つ目の画面のNULLチェックが走っているというのを、どのようにして
確認されましたか?
また、ここで言われているのは
・フォームに配置されたOKボタンのクリックイベントが、
 あるフォームのOKボタンを押すことで、生成されたすべてのフォームの
 クリックイベントを呼び出してしまう。
ということを意味していますか?

たとえば、先の私が挙げたサンプルコードのようにすると、
メッセージボックスがフォームの数分表示されるということですか?
つまり、子供フォームが3つあれば、1つのフォームのボタンクリックで
メッセージボックスが3回表示される、しかも、各フォームの情報を
メッセージとして?それとも、クリックされたフォームの情報だけが
3回表示される?

このあたりのことをハッキリさせていただければ、これを読んでいる人の
中に、検証していただける人も出てくるのではないでしょうか。

_________________
諸農和岳
Powered by Turbo Delphi & Microsoft Visual Studio 2005

十兵衛@わんくま同盟
http://blogs.wankuma.com/jubei/
KKK
大ベテラン
会議室デビュー日: 2003/10/10
投稿数: 119
投稿日時: 2004-04-21 14:01
返信ありがとうございます。

>で、ちなみに、Openメソッドの実装内容というのはどういったものなんでしょうか?
>MDIフォームということなので、私のC#での認識で言えば、
>MDIの子フォームは、自身のMdiParentプロパティにMDIのコンテナとなる
>親フォームを指定する必要があるかと思います。
>このあたりの制御も含めてOpenメソッド内に実装されていると考えても
>いいのでしょうか?そして、生成された子フォームのインスタンスを
>Show()する必要もあるかと思いますが、これもOpenの中で行われていると。

上記のことは、全てOpenメソッドの中で行っています。
なのでMDIコンテナを指定して、Showしています。

>2つ目の画面のNULLチェックが走っているというのを、どのようにして
>確認されましたか?

NULLの項目がある場合、そのコントロールのバックカラーを変えています。

>また、ここで言われているのは
>・フォームに配置されたOKボタンのクリックイベントが、
> あるフォームのOKボタンを押すことで、生成されたすべてのフォームの
> クリックイベントを呼び出してしまう。
>ということを意味していますか?
>たとえば、先の私が挙げたサンプルコードのようにすると、
>メッセージボックスがフォームの数分表示されるということですか?
>つまり、子供フォームが3つあれば、1つのフォームのボタンクリックで
>メッセージボックスが3回表示される、しかも、各フォームの情報を
>メッセージとして?それとも、クリックされたフォームの情報だけが
>3回表示される?

2つのフォームをA,Bとします。
AのOKボタンを押すと、BのNULLチェックが走り、Bのコントロールの色が
変わってしまいます。
Aはボタンは押せるけど、Aのフォームは何も動かないで、
すべてBのフォームが動いてしまうのです。

諸農さんの例で言うと、メッセージボックス自体は一つなのですが、
そのメッセージボックスを表示しているのは、後から立ち上げたフォームなのです。
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2004-04-21 14:06
諸農です。

引用:

2つのフォームをA,Bとします。
AのOKボタンを押すと、BのNULLチェックが走り、Bのコントロールの色が
変わってしまいます。
Aはボタンは押せるけど、Aのフォームは何も動かないで、
すべてBのフォームが動いてしまうのです。



1.Bのボタンを押すとどうなりますか?
2.子フォームを3つ以上作成した場合、AのOKをクリックするとどうなりますか?
  また、B,C,と他のフォームのボタンをクリックした場合はどうでしょうか?
3.再現できる最小限のコードをアップしていただけませんか?


_________________
諸農和岳
Powered by Turbo Delphi & Microsoft Visual Studio 2005

十兵衛@わんくま同盟
http://blogs.wankuma.com/jubei/
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-04-21 14:11
引用:

KKKさんの書き込み (2004-04-21 09:18) より:

Dim clsAssembly As Reflection.Assembly
Dim clsStart As Object
ここ
clsAssembly = Reflection.Assembly.LoadFile("AAA.dll")
clsStart = clsAssembly.CreateInstance("AAA.clsStart")
Call clsStart.Open()


ここの隙間が気になるのですが、どこで宣言しています?まさか、

class mdiParent
 Dim clsAssembly As Reflection.Assembly
 Dim clsStart As Object

 private sub hoge(〜)
  clsAssembly = Reflection.Assembly.LoadFile("AAA.dll")
  clsStart = clsAssembly.CreateInstance("AAA.clsStart")
  Call clsStart.Open()
 end sub
end class


とか?
KKK
大ベテラン
会議室デビュー日: 2003/10/10
投稿数: 119
投稿日時: 2004-04-21 14:50
引用:

1.Bのボタンを押すとどうなりますか?
2.子フォームを3つ以上作成した場合、AのOKをクリックするとどうなりますか?
  また、B,C,と他のフォームのボタンをクリックした場合はどうでしょうか?
3.再現できる最小限のコードをアップしていただけませんか?



1.BのOKボタンを押すと、BのNULLチェックが走ります。
  AのOKボタンを押したのと、同じ動きです。

2.フォームを何個作っても、最後に呼び出したフォームのNULLチェックが走ります。
  同じくどのフォームのOKボタンを押しても、最後に呼び出したフォームの
  NULLチェックが走ります。
3.以下にコードを記述します。
引継ぎの部分

(親画面 EXE)
・Menu_Click イベント

Dim clsAssembly As Reflection.Assembly
Dim clsStart As Object

clsAssembly = Reflection.Assembly.LoadFile("AAA.dll")
clsStart = clsAssembly.CreateInstance("AAA.clsStart")
Call clsStart.Open(Me)

(子画面 DLL)
Public Class clsStart

Public Function Open(ByRef pmrParentForm As Form)

dim AForm as A(←Form)
AForm = New A
AForm .MdiParent = pmrParentForm
AForm .Show()

End Function

End Class

スキルアップ/キャリアアップ(JOB@IT)