3

フォームBからフォームaに文字列を送信しようとすると、コードに非常に厄介な問題が発生します。エラーメッセージが表示されます:

Object reference not set to an instance of an object.

私はこのエラーに精通しており、通常はこの問題を解決する方法を知っていますが、これは異なります。

あるフォームからメインフォームに時計名を送信する必要があります。以下のコードを使用してこれを実現しようとしています。

delegate void ClockClocknameReceivedEventHandler(object sender, Clock.ClocknameReceivedEventArgs e);

    internal class ClocknameReceivedEventArgs : EventArgs
    {
        string _clockname;

        public string Clockname
        {
            get { return _clockname; }
        }

        public ClocknameReceivedEventArgs(string clockname)
        {
            _clockname = clockname;
        }
    }

    // An event that clients can use to be notified whenever the
    // elements of the list change.
    public event ClockClocknameReceivedEventHandler ClocknameReceived;

    // Invoke the Changed event; called whenever list changes
    protected void OnClocknameReceived(Clock.ClocknameReceivedEventArgs e)
    {
        ClocknameReceived(this, e);
    }

また、ボタンを押すと次のコードが実行され、その後フォームが閉じます。

OnClocknameReceived(new Clock.ClocknameReceivedEventArgs(ClockName));

エラー(オブジェクト参照がオブジェクトのインスタンスに設定されていません。)私が受け取るエラーは、

ClocknameReceived(this, e);

別のクラスからメインフォームまでまったく同じコードを使用して、正常に機能するバイト配列を送信していますが、これではエラーが発生します。

誰かアイデアはありますか?

前もって感謝します!

4

3 に答える 3

4

代理人はすることができますnull。そうでない場合にのみ呼び出しますnull

protected void OnClocknameReceived(Clock.ClocknameReceivedEventArgs e)
{
    ClockClocknameReceivedEventHandler handler = ClocknameReceived;
    if (handler != null)
    {
        handler(this, e);
    }
}

デリゲートはnull、イベントハンドラーをまだイベントにサブスクライブしていない場合です。イベントハンドラーをサブスクライブします。

formB.ClocknameReceived += FormB_ClocknameReceived;

void FormB_ClocknameReceived(object sender, Clock.ClocknameReceivedEventArgs e)
{
    MessageBox.Show(e.Clockname);
}
于 2013-02-15T14:08:04.997 に答える
1

ClocknameReceivedイベントが割り当てられているかどうか(つまり、サブスクライバーがあるかどうか)を確認していません。一般的なイベント処理コードは次のようになります。

var handler = ClocknameReceived;
if (handler != null)
{
    handler(this, e);
}

このタイプのアプローチでは、イベント ハンドラーをトリガーするまでに割り当てが解除される可能性があるため、イベント ハンドラーとの競合状態も (ある程度) 軽減されます。

コードを見ると、これを少し整理することができます。1EventArgsつには、より少ないコードでクラスを書き直すことができます。

internal class ClocknameEventArgs : EventArgs
{
    public ClockNameEventArgs(string name)
    {
        Name = name;
    }

    public string Name { get; private set; }
}

次に、フォームで特定のタイプの がある場合、デリゲートは必要ありませんEventArgs。イベントは次のように宣言できます。

public event EventHandler<Clock.ClocknameEventArgs> ClocknameReceived;

次に、どこかでこのイベントに接続します (おそらくFormCreateイベント内?):

ClocknameReceived += (sender, args) {
    FormB.PassName(args.Name);
};
于 2013-02-15T14:09:28.880 に答える
0

イベントに代理人がいるかどうかを確認する必要があります

if( ClocknameReceived != null)
    ClocknameReceived(this, e);
于 2013-02-15T14:11:07.480 に答える