none
カスタムコントロールの「Dispose」で「ArgumentException」の例外が発生する RRS feed

  • 質問

  • 次の様なカスタムコントロールで、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

     
    2008年3月21日 4:09

回答

  •  ぶるーのさんこんにちは。
     現象を回避するには以下の行を消してしまうと良いです。

    public delegate void EventHandler(object sender, EventArgs e);

     データバインディングするとプロパティ名+Changedイベントがあればそれを使おうとします。そのときdelegateの型はSystem.EventHandlerで定義されているものとして扱いますのでわざわざ自分で定義してしまうとエラーになります。

     

    2008年3月21日 6:56
  •  System.EventHandlerとして定義されているものとして扱うことについては、オンラインヘルプに何も書かれていませんが、カスタムコントロールの変更通知については以下のURLに書かれています。私にはぶるーのさんがお考えになったどちらかの方法をとること以外によい回避方法が思い浮かびません。

     

    http://msdn2.microsoft.com/ja-jp/library/xz45s2bh.aspx

     

     データバインディングの変更通知が反変性に対応してくれていればぶるーのさんがやりたいこともできたのですが。残念。

     

    http://msdn2.microsoft.com/ja-jp/library/ms173174.aspx

    2008年3月21日 11:36

すべての返信

  •  ぶるーのさんこんにちは。
     現象を回避するには以下の行を消してしまうと良いです。

    public delegate void EventHandler(object sender, EventArgs e);

     データバインディングするとプロパティ名+Changedイベントがあればそれを使おうとします。そのときdelegateの型はSystem.EventHandlerで定義されているものとして扱いますのでわざわざ自分で定義してしまうとエラーになります。

     

    2008年3月21日 6:56
  • 三輪の牛さん、回答ありがとうござます。

     

    >現象を回避するには以下の行を消してしまうと良いです。

    >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するプロパティを別に用意する

    等々の方法を講じるしかないのですかね?

     

    2008年3月21日 8:07
  •  System.EventHandlerとして定義されているものとして扱うことについては、オンラインヘルプに何も書かれていませんが、カスタムコントロールの変更通知については以下のURLに書かれています。私にはぶるーのさんがお考えになったどちらかの方法をとること以外によい回避方法が思い浮かびません。

     

    http://msdn2.microsoft.com/ja-jp/library/xz45s2bh.aspx

     

     データバインディングの変更通知が反変性に対応してくれていればぶるーのさんがやりたいこともできたのですが。残念。

     

    http://msdn2.microsoft.com/ja-jp/library/ms173174.aspx

    2008年3月21日 11:36
  • DataBindingするプロパティを別に用意する方向で、対応してみます。

     

    有益な情報、ありがとうございました。

     

    2008年3月24日 7:29
  • 解決済みですが参考までに。

    http://msdn2.microsoft.com/ja-jp/library/3b8tbfec.aspx

     

     

    2008年3月24日 13:24