tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトル初めまして
記事No4510
投稿日: 2006/11/08(Wed) 22:31
投稿者プログラム勉強中
 初めまして、早速ですが質問です。

 共通の関数を作ろうとしているのですが、型の引渡しで悩んでいます。
 
 プログラム、プロジェクトの内容は下記のとおりです。

 プロジェクト名「ルート名前空間名」 Sample

 フォーム名「クラス名」            Test1
                                  Test2
                                  Test3
                                  Test4

モジュール名                      Common

※それぞれのフォームには 関数「UserControlGotFocus」が存在します。

Module Common
    Public Sub setCtrl(ByRef Form As ※この部分が分かりません)
        Dim ctrl As Control
        For Each ctrl In Form.Controls
            AddHandler ctrl.GotFocus, AddressOf Form.UserControlGotFocus
        Next
    End Sub
End Module

上記同様で
Module Common
    Public Sub setCtrl(ByRef Form As Sample.Test1)
        Dim ctrl As Control
        For Each ctrl In Form.Controls
            AddHandler ctrl.GotFocus, AddressOf Form.UserControlGotFocus
        Next
    End Sub
End Module

にすると Test1はうまく動作しますが、当然他の2,3,4は動作しません。

引数の型をどのようにすれば全てうまく動くのか教えていただきたいです。

宜しくお願いいたします。

[ツリー表示へ]
タイトルRe: 初めまして
記事No4511
投稿日: 2006/11/09(Thu) 09:10
投稿者魔界の仮面弁士
>     Public Sub setCtrl(ByRef Form As ※この部分が分かりません)
As Form でしょうね。各フォームは、すべて Form クラスを継承(Inherits)していますから。
(名前空間を省略せずに書くなら、As System.Windows.Forms.Form で)


なお、この場合は Test1〜Test4だけでなく、すべての種類のFormクラスが処理対象となります。
もし、Test1〜Test4に限定したいのであれば、それらに共通の Interface を用意するか、
あるいは、Test1〜Test4それぞれのオーバーロードメソッドを用意してみてください。

>     Public Sub setCtrl(ByRef Form As Sample.Test1)
ここは ByRef ではなく、ByVal にすべきかと。

[ツリー表示へ]
タイトルRe^2: 初めまして
記事No4512
投稿日: 2006/11/09(Thu) 09:28
投稿者プログラム勉強中

回答ありがとうございます。

> >     Public Sub setCtrl(ByRef Form As ※この部分が分かりません)
> As Form でしょうね。各フォームは、すべて Form クラスを継承(Inherits)していますから。
> (名前空間を省略せずに書くなら、As System.Windows.Forms.Form で)

引数をFormにしてしまうと、
AddHandler ctrl.GotFocus, AddressOf Form.UserControlGotFocus
でUserControlGotFocusがメンバーではありません。とエラーになってしまいます。

> なお、この場合は Test1〜Test4だけでなく、すべての種類のFormクラスが処理対象となります。
> もし、Test1〜Test4に限定したいのであれば、それらに共通の Interface を用意するか、
> あるいは、Test1〜Test4それぞれのオーバーロードメソッドを用意してみてください。

今回はこの共通関数をライブラリにして色々なプロジェクトから呼べたらと思っています。
なのでTest1〜Test4に限定しなくても良いのですが、やはりこの書き方では無理なような気がします・・・。

質問ばかりで恐縮ですが、引数で AddressOf 〜 の〜の部分を引き渡すのは可能でしょうか?
たとえば

Public Sub setCtrl(ByRef Form As System.Windows.Forms.Form,Byval Address as ※不明)
      Dim ctrl as Control
      For Each ctrl In Form.Controls
          AddHandler ctrl.GotFocus AddressOf Address
      Next
End sub

のようにできたらいいのですが。

> >     Public Sub setCtrl(ByRef Form As Sample.Test1)
> ここは ByRef ではなく、ByVal にすべきかと。

そのとおりですね!Byvalに変更します。ご指摘ありがとうございます。

[ツリー表示へ]
タイトルRe^3: 初めまして
記事No4513
投稿日: 2006/11/09(Thu) 09:47
投稿者プログラム勉強中
連投すいません。
解決しましたのでご報告します。

1.引数の型をFromに変更
2.関数UserControlGotFocusを各フォームからモジュール内に変更
3.ByrefをByvalに変更

上記のように変更し解決しました。

これで後は各フォームのLoad か New でこの関数を呼び出せばうまく動きました。

魔界の仮面弁士さん、ありがとうございました。

[ツリー表示へ]
タイトルRe^3: 初めまして
記事No4514
投稿日: 2006/11/09(Thu) 09:52
投稿者魔界の仮面弁士
> AddHandler ctrl.GotFocus, AddressOf Form.UserControlGotFocus
> でUserControlGotFocusがメンバーではありません。とエラーになってしまいます。
そのメンバを持つ型にキャストするか、もしくは、そのメンバを持つ型のみを
受け取れるように、先の回答のような方法を採用するか…という事になるかと。
もし、UserControlGotFocus メソッドの内容が、各フォームで共通なのであれば、
そのイベントハンドラを各Formで管理するのではなく、管理用のクラスもしくはモジュールを
用意しておき、そちらに UserControlGotFocus 相当のメソッドを実装するのも手かと。


> 質問ばかりで恐縮ですが、引数で AddressOf 〜 の〜の部分を引き渡すのは可能でしょうか?
『デリゲート』について調べてみてください。

Public Sub SetCtrl(ByVal form As Form, ByVal gotFocusHandler As EventHandler)
    For Each ctrl As Control In form.Controls
        AddHandler ctrl.GotFocus, gotFocusHandler
    Next
End Sub

[ツリー表示へ]