1

カスタム コンポーネントを含む WinForms アプリケーションを作成しました。

コンポーネントは起動時にそのイベントの 1 つを起動する必要がありますが、コンポーネントのコンストラクターが呼び出された時点では、すべてのイベント ハンドラーはまだ null です。

必要なのは、コンポーネントを所有するウィンドウが読み込まれ、すべてのイベント ハンドラーが設定されたことを通知するイベントです。

ただし、コンポーネントにはLoadイベントがないようです。実際、イベントを除いて、イベントはまったくないようDisposedです。

コンポーネントは、起動時にイベントを発生させても安全であることをどのように知ることができますか?

4

2 に答える 2

1

考えられる解決策の 1 つは、コンポーネントがリスナーに接続されているときにイベントを発生させることです。独自のイベント プロパティを作成する必要があります。

class MyClass
{
    private static readonly _myEvent = new object();

    private EventHandlerList _handlers = new EventHandlerList();

    public event EventHandler MyEvent
    {
        add 
        { 
            _handlers.AddHandler(_myEvent, value); 
           OnMyEvent(); // fire the startup event
        }
        remove { _handlers.RemoveHandler(_myEvent, value); }
    }

    private void OnMyEvent()
    {
        EventHandler myEvent = _handlers[_myEvent] as EventHandler;
        if (myEvent != null) myEvent(this, EventArgs.Empty);
    }

    ...

}
于 2013-06-27T00:35:26.727 に答える
0

少なくとも 2 つの異なる方法があります。
1 つ目の方法は、設計時に Site を使用してコンテナーを追跡することです (Site は実行時に呼び出されません)。設計時に ContainerControl プロパティを保存するだけで機能するため、実行時に使用できます。フレームワークの一部のコンポーネントのプロパティ ブラウザで確認できます。

    private ContainerControl _containerControl;

    [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
    public ContainerControl ContainerControl
    {
        get { return _containerControl; }
        set
        {
            _containerControl = value;
            if (DesignMode || _containerControl == null)
                return;

            if (_containerControl is Form)
                ((Form) _containerControl).Load += (sender, args) => { Load(); };
            else if (_containerControl is UserControl)
                ((UserControl)_containerControl).Load += (sender, args) => { Load(); };
            else
                System.Diagnostics.Debug.WriteLine("Unknown container type. Cannot setup initialization.");
        }
    }

    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    [Browsable(false)]
    public override ISite Site
    {
        get { return base.Site; }
        set
        {
            base.Site = value;
            if (value == null)
                return;

            IDesignerHost host = value.GetService(typeof(IDesignerHost)) as IDesignerHost;
            if (host == null)
                return;

            IComponent componentHost = host.RootComponent;

            if (componentHost is ContainerControl)
                ContainerControl = componentHost as ContainerControl;
        }
    }

    private void Load()
    {

    }

2 番目の方法は、コンポーネントに ISupportInitialize を実装することです。この場合、設計時に Visual Studio (2013) は、コンポーネントで ISupportInitialize メソッド (BeginInit および EndInit) を呼び出すコードを生成します。

于 2015-06-23T13:42:21.533 に答える