
実行時にコントロールのイベントの登録/解除を、イベントハンドラのメソッドをあらかじめ知っていないロジックから実施する方法
通常、実行時にコントロールにイベントの登録/解除
を行う際は。
AddHandler 対象コントロール.イベント名, AddressOf メソッド
RemoveHandler 対象コントロール.イベント名, AddressOf メソッド
や
AddHandler 対象コントロール.イベント名, メソッドのデリゲート型
RemoveHandler 対象コントロール.イベント名, メソッドのデリゲート型
を行うと思います。
しかし、この方法では、これを実施するロジックが
AddressOf メソッド
や
メソッドのデリゲート型
を知っていなければなりません。
そうではなく、それをあらかじめ、知っていなくても
対象コントロール から
AddressOf メソッド
や
メソッドのデリゲート型
に該当するオブジェクトを取得するなどして、
実施できる方法を教えてください。
言語は、.NET系であれば。。
VB.NET, C#, C++のいづれかでもよいです。
できさえすればよいです。
J#とか、Delphi.NETとかマイナーなのは、厳しいです。
なお、C++でもしできるのであれば。
2003のマネージC++と、
2005のC++/CLIの両方について知りたいです。
以上、よろしくお願いします。
A 回答 (4件)
- 最新から表示
- 回答順に表示
No.4
- 回答日時:
う~ん。
何だか厳しいような気がしてきました・・・このソースの全容を理解しないままの回答なので、間違いがあるかもしれませんので、疑いながら読んでください。
EventHandlerListについて、MSDNライブラリを読んでみると、
( http://msdn2.microsoft.com/ja-JP/library/8843a9c … )
イベントを大量にもっているクラスの場合、ハンドルされない可能性の高いイベントをひとつずつ変数で管理するのはメモリの無駄だから用意されている機構のようで、これのキーになっているオブジェクトは一意でさえあれば何でも良いように見えますね・・・
それで、このキーを特定するのが最初のソースの
private static FieldInfo GetEventIDField(Type objType, string eventName)
の中身だと思うんですが、取得するフィールド名を "Event"+eventName と決め打ちしてしまっているので、.Net Frameworkに標準のクラスはこの命名規則に従っていそうな雰囲気ではありますが、これを守る義務のないサードパーティ製のものだとダメですよね、多分。
時間を無駄にさせてしまいまして申し訳ありませんが、どうも何か別な手段が必要そうです・・・
No.3
- 回答日時:
試していませんが、おっしゃる内容に近いのではないかというをやっているコードがあります。
http://www.technewsgroups.net/group/microsoft.pu …
中身を良く読んでいないので、これでうまくいくかわかりませんし、サードパーティ製のコンポーネントの場合、同じ方法が使えるのかも不明です。
ひょっとすると、System.Reflection名前空間を調べてみると良い方法が見つかるかもしれませんよ。
参考URL:http://www.technewsgroups.net/group/microsoft.pu …
回答ありがとうございます。さっそく、
↑のサイトのソースを参考にして、
EventDescriptorCollection events = TypeDescriptor.GetEvents(myComponent);
foreach (System.ComponentModel.EventDescriptor myEvent in events)
{
のループの中で
EventDescriptorのNameプロパティと
自分が現在、注目しているイベントの名前
("Click"などの文字列)とを比較すると、
自分が注目している該当イベントの
EventHandlerListオブジェクトジェクトの取得まで
できるところまでこぎつけました。
EventHandlerListのVBでいうところのデフォルトプロパティとして定義されたitemプロパティ、C#でいうところのにインデクサに相当するものは、
object keyを引数にとり、
System.Delegateを取得できるようです。
なので、このSystem.Delegateを取得できれば、
AddHandlerやRemoveHandlerのカンマの後ろにくる
披演算子として使えます。
ところが、このobject keyに何を与えても
Nothingしか帰って来ない、いったい何をキーとして
要求するかの仕様がいまいちわからないです。
メソッド名や、イベント名やクラス名などおもいあたるものをいろいろ与えて試してもNothingしかかえってこないです。
しょうがないのでEventHandlerListオブジェクトそのものをforeach構文のinの後ろにもっていって、
System.Delegate型で取得しながら、ループをまわして、AddHandlerなり、RemoveHandlerをやってやろうと
おもいましたが、EventHandlerListオブジェクトが
コレクションではないという理由でコンパイルエラーになってしまいました。
○○Listって名前からして、いけそうに見えたのですが残念です。
EventHandlerListオブジェクトのヘルプを見てみましたが、インデクサのobject keyになにを入れたら、
System.Delegate型を取得できるか?の仕様や?
System.Delegate型のコレクションをあらわす、プロパティやそれを取得できるメソッドといったメンバが見当たらず。
お手上げになってしまいました。・・・・・
No.2
- 回答日時:
お世話になります。
AddHandler 及び RemoveHandler
で追加したり削除したりする対象のイベントを
知らないでやる事は出来ないと思います。
私も前に、サードパーティ製品を使って
どうにもそのコントロールの挙動が
望むものと違ったとき、
そのコントロールを継承したクラスを作って
挙動を変えたいイベントを突き詰めて
オーバーライドして逃げた記憶があります。
> とりあえずは、グローバル領域にフラグをたてて、
> メソッドの先頭で、フラグをたてて、後処理でおろす
この方法と似ていますが、
その自身で拡張したクラスに独自プロパティを設けて
そのプロパティの値を見て
オーバーライドしたイベントハンドラ内で
何かする、という方法です。
No.1
- 回答日時:
お世話になります。
> そうではなく、それをあらかじめ、知っていなくても
> 対象コントロール から
> AddressOf メソッド
> や
> メソッドのデリゲート型
> に該当するオブジェクトを取得するなどして、
> 実施できる方法を教えてください。
?
それだったら、普通に、そのオブジェクトの振る舞いとして、
AddressOf 等で定義付けるのではなくて
初めから実装しておけばよいのでは?
その該当クラスの該当メソッドが
外部クラスから操作することありきでやるのであれば
インターフェースや抽象クラスを使った上で
そのような実装を行うような設計を
した方がよさそうな感じはしますけれども。
この回答への補足
回答ありがとうございます。
説明不足でしたので補足します。
>その該当クラスの該当メソッドが
>外部クラスから操作することありきでやるのであれば
>インターフェースや抽象クラスを使った上で
>そのような実装を行うような設計を
>した方がよさそうな感じはしますけれども
イベントの設定/解除を行いたい対象オブジェクトが
自作クラスのオブジェクトであればもちろんそのように致します。
外部のサードパーティー製のユーザコントロール(DLLとNDoc提供のみ)のオブジェクトを使っている部分のプログラムのお話でして、そのユーザコントロール
のあるプロパティ値を変更した時、意図しないイベントが走ってしまいます。
通常は、ユーザが画面操作を行った時に変更される
プロパティなのですが、その際には、イベント処理が走ります。
問題は、プログラムからそのプロパティを変更した時にイベントが走ってしまう。
のを回避したかったんです。
実は、現在開発しているシステムの一部は、
多言語(.NET系ではない)で作られた旧システムの
ソースをコンバートすることで作ってる部分があります。
旧システムで使ってるコントロールと近いサードパーティー製のユーザコントロールを使っていたのですが。
旧システムの言語仕様では、↑のプロパティに該当するプロパティをプログラムから変更した時に、
イベントが発生しない仕様になっています。
旧システムのコントロールを使い勝手と、
新システムのコントロールの使い勝手が異なるため、
その違いを吸収したり、言語間の仕様の違いを吸収するために、プロパティの値の設定や、解除に対応する
ユーティリティメソッドを作って、その中で、
出てきた問題などを吸収して、開発をすすめていました。
そして、今回のイベントが発生する/しないの
問題をそのメソッドの中で吸収したいのですが
そのメソッドの中には、コントロールと、設定値
の2つの引数しかとるようになっていないです。
実際に該当する画面で、該当インスタンスに関連づいたコントロールのメソッドを知ることができないんです。
じゃー、そのメソッドがそれを引数にとればいいじゃないですか?
といわれそうですが。。。
プログラムのコードからその種類のプロパティを
設定/解除しているコードは大量にあります。
また、今後も似たような問題はでるかもしれないです。
メソッドの中は、
イベントの解除をおこない、
プロパティ値の設定をおこない、
イベントをまた、元に戻す。
ようにしたいです。
ある程度のモジュール数を作らないと、動作ができない物理的な事情や、工数の問題から旧システムからの移行部分に関してはこのような手法で、作ってます。
なので、既に、この問題を解決しなければならない多くのコードに、対して、引数追加はせず、完全にイベントハンドラのメソッドを知らないロジックから
できる方法が知りたいんです。
とりあえずは、グローバル領域にフラグをたてて、
メソッドの先頭で、フラグをたてて、後処理でおろす
イベントハンドラ側の先頭ではフラグがたっていれば
なにもしない
というロジックをいれることで回避できるみたいです。
プログラムのコードからプロパティ値を設定している
コードよりも、イベントハンドラの定義の数のほうが
少ないのでその方法で逃げれそうですが。
本当は、それもしたくないんです。
そういう経緯があって今回の質問をしました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(プログラミング・Web制作) pythonでクラスで複数のメソッドを利用する方法 2 2022/04/15 04:17
- その他(プログラミング・Web制作) Pythonで複数のメソッドをまとめて管理する方法について 1 2023/03/30 00:01
- Java java 飾子を付けること(public static・・・) ・コンソールへの出力処理はmainメ 2 2022/06/16 19:34
- Java java 次の機能を有するメソッドを自クラスに作成し、実装したいです。 機能 名前判定機能 →名前が 3 2022/06/16 16:08
- Visual Basic(VBA) セルS2に入力した「月」と一致したB列の右隣へセルS110の値を転記する下記マクロを実行するとエラー 2 2022/12/06 17:32
- Java javaの質問です 次の機能を有するメソッド4つを自クラスに作成し、実装したいです 【機能】 足し算 1 2022/06/15 17:49
- Visual Basic(VBA) vbaエクセルマクロについて RemoveDuplicatesを使わずに、重複行を削除すらマクロを作 3 2023/03/02 22:03
- C言語・C++・C# ActiveXコントロールを.NETにインポートできない??? 2 2023/05/02 02:50
- Visual Basic(VBA) VBAのSelectedIndexでコンパイルエラーが… 1 2023/04/16 14:07
- その他(プログラミング・Web制作) pythonのプログラムについての質問です。 1 2023/05/26 10:31
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
実行時にコントロールのイベン...
-
画面遷移が不正ですと表示されます
-
C#でドラッグ&ドロップが機能し...
-
VBAで一時中断したプログラムの...
-
Accessの画面更新を一時的に停...
-
コネクション・セッション・ト...
-
getParameterで値が取得できず...
-
PageLoadの後にJavascript実行...
-
コンピュータへの接続数が最大...
-
グーグルマップの文字化けで困...
-
c# 文字列の最後から1文字削除...
-
ページングが大量発生する原因...
-
パスワードつきホームページ ト...
-
セッションIDを取得したい
-
aspxをhtmlに変換する方法について
-
Eclipseでクリーンが出来ない
-
ボタンをクリックした時に、入...
-
TabStripのイベントについて
-
ボタンのなかに表示する文字を...
-
特定の端末からのみWebシステム...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
同じソリューション内の別のプ...
-
実行時にコントロールのイベン...
-
VB.NET
-
WinHttpをC#で使用したい
-
EXCEL VBAをWEB上で実行し...
-
VBAで一時中断したプログラムの...
-
コネクション・セッション・ト...
-
Accessの画面更新を一時的に停...
-
HTMLボタンの文字色を変え...
-
c# 文字列の最後から1文字削除...
-
コンピュータへの接続数が最大...
-
DVD-Rの「セッションを閉じる」...
-
ボタンのなかに表示する文字を...
-
Eclipseでクリーンが出来ない
-
SPREADでカーソルの位置を1行目...
-
DataGridViewのチェックボック...
-
Webページ上のボタン等の位置を...
-
ASPで画面間のパラメタ受け渡し
-
ACCESS2010 WEBブラウザーコン...
-
複数選択のListBoxでClickイベ...
おすすめ情報