Question

I am trying to use the information from the Passing-Data-between-Windows-Forms white paper to write some custom events to pass information between forms.
Unfortunately, I keep getting a NullReferenceException when I attempt to raise the event. Below is a scaled down version of the relevant code that I have currently attempted.
Can someone please have a look and let me know if I am missing something?
BTW, I am using DevExpress forms if that makes a difference. I only included the class that is generating my custom event since that is where the code is failing. On the line where the NullReferenceException occurs, I have verified that the item is not 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:
Was it helpful?

Solution 2

You don't have any event handlers attached. Usually custom event code has a check for that:

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

You need to have some code somewhere that adds a handler, i.e.

MyObject.ItemInsertedEvent += myHandler;

EDIT: Jon Skeet is right about race condition issues, you should use the local variable like he suggests. I've changed my example to match.

OTHER TIPS

Chances are you don't have any subscribers for the event. If that's the case, the delegate field which backs your event will have a null value. You should check for that, like this:

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

The reason for using a local variable is to avoid a race condition, where the last handler is removed after the check but before the invocation.

This is because the event is null when you're calling it. You need to check if it's null beforehand:

if (ItemInsertedEvent != null) {
    ItemInsertedEvent(this, args);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top