0

Passing-Data-between-Windows-Formsホワイト ペーパーの情報を使用して、フォーム間で情報を渡すカスタム イベントを作成しようとしています。
残念ながら、NullReferenceExceptionイベントを発生させようとすると、エラーが発生し続けます。以下は、私が現在試みた関連コードの縮小版です。
誰かが見て、何かが足りないかどうか教えてもらえますか?
ところで、それが違いを生む場合、私は DevExpress フォームを使用しています。コードが失敗する場所であるため、カスタムイベントを生成しているクラスのみを含めました。が発生している行でNullReferenceException、アイテムが ではないことを確認しましたnull

// Class that generates custom event
public partial class DiscountItemControl : DevExpress.XtraEditors.XtraUserControl
{
    // Add a delegate
    public delegate void ItemInsertedEventHandler(object sender, ItemInsertedEventArgs e);

    // AddCustomerForm an event of the delegate type
    public event ItemInsertedEventHandler ItemInsertedEvent;

    public void SaveAndClose()
    {
        // setup event args
        ItemInsertedEventArgs args = new ItemInsertedEventArgs(currentDiscountItem);

        // ********** THIS THROWS NullReferenceException *********
        // raise the event to notify listeners
        ItemInsertedEvent(this, args);

        this.Dispose();
    }
}

// Event arguments for event
public class ItemInsertedEventArgs : System.EventArgs
{
    private Item item;

    public ItemInsertedEventArgs(Item item)
    {
        this.item = item;
    }

    public Item InsertedItem
    {
        get
        {
            return this.item;
        }
    }
}

System.NullReferenceException was unhandled by user code   Message="Object reference not set to an instance of an object."   Source="PureService"   StackTrace:
at MarineService.Tests.DiscountItemControl.SaveAndClose(Boolean& result) in C:\Aaron\Dev\HIGH PRIORITY\ServiceModule\MarineService\ServiceModule\UtilityClasses\UserControls\Items\DiscountItemControl.cs:line 336
at MarineService.Tests.AddEditItemForm.btnSaveAndClose_Click(Object sender, EventArgs e) in C:\Aaron\Dev\HIGH PRIORITY\ServiceModule\MarineService\ServiceModule\AddEditItemForm.cs:line 326
at System.Windows.Forms.Control.OnClick(EventArgs e)
at DevExpress.XtraEditors.BaseButton.OnClick(EventArgs e)
at DevExpress.XtraEditors.BaseButton.OnMouseUp(MouseEventArgs e)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at DevExpress.Utils.Controls.ControlBase.WndProc(Message& m)
at DevExpress.XtraEditors.BaseControl.WndProc(Message& msg)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)   InnerException:
4

3 に答える 3

4

イベントのサブスクライバーがいない可能性があります。その場合、イベントをサポートするデリゲート フィールドは null 値になります。次のように、それを確認する必要があります。

ItemInsertedEventHandler handler = ItemInsertedEvent;
if (handler != null)
{
    handler(this, args);
}

ローカル変数を使用する理由は、最後のハンドラーがチェックの後、呼び出しの前に削除される競合状態を回避するためです。

于 2013-01-22T23:08:13.410 に答える
1

イベント ハンドラがアタッチされていません。通常、カスタム イベント コードにはそのチェックがあります。

ItemInsertedEventHandler handler = this.ItemInsertedEvent;
if(handler != null) handler(this, args);

ハンドラーを追加するコードがどこかに必要です。つまり、

MyObject.ItemInsertedEvent += myHandler;

編集: Jon Skeet は、競合状態の問題について正しいです。彼が提案するように、ローカル変数を使用する必要があります。一致するように例を変更しました。

于 2013-01-22T23:08:30.350 に答える
0

これは、イベントがnull呼び出されているためです。null事前に確認する必要があります。

if (ItemInsertedEvent != null) {
    ItemInsertedEvent(this, args);
}
于 2013-01-22T23:09:22.793 に答える