トップ回答者
カスタムコントロールの「Dispose」で「ArgumentException」の例外が発生する

質問
-
次の様なカスタムコントロールで、Form終了(閉じる)時に、カスタムコントロールの「Dispose」で
「ArgumentException」「型 'System.EventHandler' のオブジェクトを型
'WindowsApplication1.TextBoxCustom+EventHandler' に変換できません。」の例外が発生します。
public partial class TextBoxCustom : TextBox
{// イベント関連 ここから
public delegate void EventHandler(object sender, EventArgs e);
public event EventHandler SelectedValueChanged;protected virtual void OnSelectedValueChanged(EventArgs e)
{
if (SelectedValueChanged != null)
{
SelectedValueChanged(this, e);
}
}// イベント関連 ここまで
// プロパティ関連ここから
private string _selectedValue;public string SelectedValue
{
get { return _selectedValue; }
set { _selectedValue = value; }
}
// プロパティ関連ここまで
}発生する場所は、「base.Dispose(disposing);」です。
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}例外が発生する条件は
1) カスタムコントロールに「SelectedValue」という名のプロパティが存在
2) カスタムコントロールにイベント関連(ソース内「イベント関連ここから」から「イベント関連ここまで」の部分)
のコーディングが存在
3) Formに貼り付けたカスタムコントロールに対し、DataBindingする。
(Form1.Designer.csより)
this.textBoxCustom1.DataBindings.Add(new System.Windows.Forms.Binding("SelectedValue", this.BindingSource, "FIELDNAME", true));
この何れか1つでも欠けると、例外は発生しなくなります。
例えば、
1) について、プロパティ名を「SelectedValue」->「SelectedValue2」と名前を変える。
2) について、ソース内「イベント関連ここから」から「イベント関連ここまで」の部分をコメントアウトする。
3) について、DataBindingをしない
ちなみに、例に挙げたカスタムコントロールは、「TextBox」から継承してますが、「Control」「GroupBox」
でも同様に例外が発生しました。(全てのコントロールについては試していません)
何がいけないのか良く分からなくて、皆様、ご教授願えませんでしょうか。
宜しくお願い致します。
環境:
Windows Vista Ultimate
Visual Studio 2005 Professional Edition SP1
.NET Framework 2.0
回答
-
System.EventHandlerとして定義されているものとして扱うことについては、オンラインヘルプに何も書かれていませんが、カスタムコントロールの変更通知については以下のURLに書かれています。私にはぶるーのさんがお考えになったどちらかの方法をとること以外によい回避方法が思い浮かびません。
http://msdn2.microsoft.com/ja-jp/library/xz45s2bh.aspx
データバインディングの変更通知が反変性に対応してくれていればぶるーのさんがやりたいこともできたのですが。残念。
すべての返信
-
三輪の牛さん、回答ありがとうござます。
>現象を回避するには以下の行を消してしまうと良いです。
>public delegate void EventHandler(object sender, EventArgs e);
確かに、削除すると例外が発生しなくなりました。
>delegateの型はSystem.EventHandlerで定義されているものとして扱います
これって、仕様なんですかね?
ゆくゆくは、「EventArgs」も独自のクラスにする予定だったので、あえて「delegate」を
記述していました。
こんな感じにする予定でした。
public class MyEventArgs : EventArgs
{
}public delegate void MyEventHandler(object sender, MyEventArgs e);
public event MyEventHandler SelectedValueChanged;>データバインディングするとプロパティ名+Changedイベントがあればそれを使おうとします。
しかし、この仕様がある以上、DataBindingするプロパティに「プロパティ名+Changed」イベント
を作成したいと思った場合は、独自のEventArgsを使用してはいけない、という事になるんでしょうか?
独自のEventArgsでイベントを作成したければ、
1) イベント名を「プロパティ名+Changed」にならない様に命名する
2) Bindするプロパティを別に用意する
等々の方法を講じるしかないのですかね?
-
System.EventHandlerとして定義されているものとして扱うことについては、オンラインヘルプに何も書かれていませんが、カスタムコントロールの変更通知については以下のURLに書かれています。私にはぶるーのさんがお考えになったどちらかの方法をとること以外によい回避方法が思い浮かびません。
http://msdn2.microsoft.com/ja-jp/library/xz45s2bh.aspx
データバインディングの変更通知が反変性に対応してくれていればぶるーのさんがやりたいこともできたのですが。残念。
-