Click here to Skip to main content
15,891,204 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have a class, Widget, which is a userControl. Widget contains a custom class, CustomImageViewer.

CustomImageViewer publishes messages via a very simple event. Widget subscribes to this event and, when it is raised, throws it's own event to pass along the CustomImageViewer message, along with some of it's own info.

Here's the code from the Widget class which passes along the message:

C#
void civImgView_NoteSent(string theMessage, cvMessaging.messageStatus theStatus)
        {
//we recieved a message from the civImgView_NoteSent.  Just pass it along.
this.NoteSent("Control " + ID.ToString() + ": " + theMessage, theStatus);
            
        }


The widgets are added to a flow layout panel by a background worker thread. The problem I'm having is that, at random, the above line "this.NoteSent("Control " +..." throws an error stating "object reference not set to an instance of an object".

Changing the above to the following prevents the error:

C#
void civImgView_NoteSent(string theMessage, cvMessaging.messageStatus theStatus)
        {

            //we recieved a message from the civImgView_NoteSent.  Just pass it along.
            if (this.NoteSent != null)
            {
this.NoteSent("Control " + ID.ToString() + ": " + theMessage, theStatus);
            }
            
        }

I'm obviously only getting a few of the messages when I do that though...

"NoteSent" is an event defined in the widget class like this:

C#
public partial class cvWidget : UserControl
  {



      private delegate void delStringOnly(string theString);
      private delegate void delNoVar();

      //Standard event to be raised when the widget has a message to give to someone who cares.
      public event cvMessaging.delMessageDelegate NoteSent;
      //the id of this widget - defined by the calling class
      public int ID { get; set; }


So what am I missing? How can the event "NoteSent" not exist, if the place where it is raised is WITHIN the class where the error is raised? Does that make sense? How can the Widget class run the "civImgView_NoteSent" sub if it is not instantiated, and if the Widget is, how can the event not be?

Sorry if that's poorly phrased, but hopefully you get what I'm asking. Here's the code for the first part of the class:

C#
 public partial class cvWidget : UserControl
    {

        

        private delegate void delStringOnly(string theString);
        private delegate void delNoVar();

        //Standard event to be raised when the widget has a message to give to someone who cares.
        public event cvMessaging.delMessageDelegate NoteSent;
        //the id of this widget - defined by the calling class
        public int ID { get; set; }
        private CustomImageViewer civImgView;

        //if the contained CustomImageViewer is selected then this should be passed
        //on as a property of this control as well
        public bool isSelected
        {
            get
            {
                if (this.civImgView.selectedState == CustomImageViewer.selectedStates.Selected)
                { return true; }
                else { return false; }


            }
        }
        //The path to the file this widget represents
        private string _filePath;
        public string filePath
        {
            get
            {
                return _filePath;
            }

            set
            {
                _filePath = value;
                setFileLabel();
                setWidgetImage();
            }
        }
        



        public cvWidget()
        {
            InitializeComponent();

            // 
            // civImgView
            // 
            this.civImgView = new CleanViewLib.CustomImageViewer(this);
            this.Controls.Add(civImgView);
            this.civImgView.BackColor = System.Drawing.Color.Gray;
            this.civImgView.Location = new System.Drawing.Point(3, 3);
            this.civImgView.Name = "civImgView";
            this.civImgView.Padding = new System.Windows.Forms.Padding(1);
            this.civImgView.Size = new System.Drawing.Size(112, 82);
            this.civImgView.TabIndex = 2;
            //set up event handler that handles messages sent from the image viewer.  These
            //get passed on from this controls message event as well
            this.civImgView.NoteSent += new cvMessaging.delMessageDelegate(civImgView_NoteSent);
        }

        void civImgView_NoteSent(string theMessage, cvMessaging.messageStatus theStatus)
        {

            //we recieved a message from the civImgView_NoteSent.  Just pass it along.
            if (this.NoteSent != null)
            {
this.NoteSent("Control " + ID.ToString() + ": " + theMessage, theStatus);
            }
            
        }


I know the issue has something to do with the fact that the widgets are added as part of the background thread, but I still don't get how the event can not exist is the object itself that contains it does...

Thanks a bunch.

Rune
Posted
Comments
rune711 28-Oct-12 19:02pm    
Brilliant. My problem was that I would create an instance of the Widget and assign the image to the customImageViewer, which sometimes created a message. Meanwhile in the base class that created the widget the event handler wasn't assigned until AFTER the image was assigned to customImageViewer. When it ran, obviously sometimes the message didn't exist until AFTER the image was finished being assigned, thus the periodic issue. Now with the event handler assigned first, no problems. Thanks!

1 solution

Practically speaking there is no existence of an Event. The event will always give a null if it is not subscribed to an event handler.

this.NoteSend == null when no eventhandler is subscribed to it.
this.NoteSend != null when one or more eventhandler is subscribed to it.


So it is always a good idea to wrap the NoteSend inside an if block such that if you are just creating the object without subscribing to an event handler it runs smoothly.

You got my point ?
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900