0

I know this is a noob error but I really can't discover why it's coming up as I am accessing an object that is set.

The xloc and yloc both being local variables.

gameBorder.FormInstance.tableLayoutPanel1.GetControlFromPosition(xloc, yloc).BackgroundImage = Properties.Resources.Image;

However this has been set within the form class:

namespace csharp_build
{
    public partial class gameBorder : Form
    {
        public static gameBorder FormInstance;

        public gameBorder()
        {
            FormInstance = this; 
            InitializeComponent();            
        }
    }
}

Any idea why this happens? Would it be to do with the fact that the form class is referenced as gameBorder, and that is what the constructor is called, and the name for the form class in the solution explorer is Form1.cs?
I know this is a noob problem and I do apolagize but any help would be greatly appreciated.

Fedor
  • 1,548
  • 3
  • 28
  • 38
  • where are `xloc` and `yloc` being set? – rory.ap Apr 23 '14 at 14:52
  • 2
    i bet `GetControlFromPosition` is returning null. Try Splitting it out like: `var temp = gameBorder.FormInstance.tableLayoutPanel1.GetControlFromPosition(xloc, yloc)` and check the value of `temp` – Jonesopolis Apr 23 '14 at 14:53
  • 4
    what happen if there is no control at the coordinates requested? It returns NULL and you try to read the BackgroundImage of NULL. [What is a NullReferenceException?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – Steve Apr 23 '14 at 14:53
  • 3
    Chaining together indirections is hiding the null. Step #1 in debugging this is to check each step: is `FormInstance` null? Is `tableLayoutPanel`? Does `GetControlFromPosition()` return anything? is `Properties.Resource.Image` non-null? Use your IDE's debugging tools. –  Apr 23 '14 at 14:55

2 Answers2

2

If you are sure that tableLayoutPanel1 exists and is not null, then change your code to this and see what happens:

  var control = gameBorder.FormInstance.tableLayoutPanel1.GetControlFromPosition
      (xloc, yloc);
  if (control == null) throw new NullReferenceException(
           "No control at those coordinates");
  control.BackgroundImage = Properties.Resources.Image;

jeez, guys, this is code for analysis, debugging, to help figure out illustrate the cause of the issue, that's all.....

WARNING WARNING WARNING: NOT INTENDED AS FINAL PRODUCTION CODE
Thanks to @SriramSakthivel comments below, please Note that NullReferenceException is being thrown here only for debugging/Analysis purposes, and should never be thrown by application code in production release.

Charles Bretana
  • 143,358
  • 22
  • 150
  • 216
  • 2
    `NullReferenceException` is a reserved exception. should never be thrown from user code. – Sriram Sakthivel Apr 23 '14 at 14:58
  • @SriramSakthivel source? – reggaeguitar Apr 23 '14 at 14:59
  • @reggaeguitar, well the basic premise would be that `InvalidOperationException` is likely more appropriate here. But it's splitting hairs at best. – Mike Perrenoud Apr 23 '14 at 15:00
  • 4
    @Siriam, don't be pedantic, this is intended to illustrate/uncover/analyze the issue, Have you heard of the concept "Debugging" ?? – Charles Bretana Apr 23 '14 at 15:00
  • 1
    For debugging purposes `Debug.Assert` would be far more appropriate here. – Crono Apr 23 '14 at 15:01
  • 1
    @SriramSakthivel, kudos for the source. :D – Mike Perrenoud Apr 23 '14 at 15:02
  • @Crono, if this was intended to remain in the production code, then you might be right, but AS SOON AS WE KNOW WHAT THE ISSUE IS, THIS CODE NEEDS TO BE REWRITTEN ANYWAY – Charles Bretana Apr 23 '14 at 15:03
  • 1
    @CharlesBretana Your illustration can be with right exception type isn't it? Who knows this is for illustration? May future visitors be misleaded through this. – Sriram Sakthivel Apr 23 '14 at 15:03
  • if (control == null) throw new NullReferenceException( "No control at those coordinates"); thorws the exception that says there is no control at these co ordinates? – Skippeh1234 Apr 23 '14 at 15:05
  • @Siriam, For what this is for, it doesn't need an exception at all, it could be System.Exception, it could pop a message box, or break, or I really don't think it matters enough to justify even one comment here... much less to quibble over what might be the "right" exception.... – Charles Bretana Apr 23 '14 at 15:07
  • @CharlesBretana the point here is not how bad this code is. It's only about how it could be better. Remember that there's a learning community on SO. Comments about how stuff could be done better should not only be expected but encouraged. – Crono Apr 23 '14 at 15:10
  • @user337.. Then what that is telling you is that the values you are passing in `xloc` and `yloc` are for a position on the screen where there is no control, so the line that should be populating the variable `control` is returning a null. – Charles Bretana Apr 23 '14 at 15:11
  • Does the fact that its thrown the null reference exception mean that the tablelayoutpanel does not exist? or that the instance of the form that it's on, does not exist? – Skippeh1234 Apr 23 '14 at 15:11
  • @CharlesBretana Why are you not getting my point? Assume I'm dumb, a newbie, etc. I will never understand that this is for debugging. All what I can see is a veteran with 56.3k reputation shown a example to throw `NullReferenceException`, so a beginner will be misleaded, If i'm a beginner I'd have misleaded and I'd start to believe intuitively I should throw null reference exception where I see objects are null. Got my point? My intention is not to offend you. We all together lead beginners to right way. Agree? – Sriram Sakthivel Apr 23 '14 at 15:12
  • @user337, No if it got to the line that throws the exception, then `tablelayoutpanel ` must exist, it's the function that attempts to "find" the control at those coordinates is returniung a null cause there is no control there. – Charles Bretana Apr 23 '14 at 15:13
  • @Sirriam, My apologies for appearing to not get your point. My answer said to rewrite the code as shown "And see what happens" If that is not a clear enough reference to debugging, even for a newby, then I will stand corrected, but, imho, it is. Granted, I could have said "temporarily, or explicitly used the word "debugging" but if that's all we're disagreeing about, we're expending a great deal of brain cycles over a minor semantic point. – Charles Bretana Apr 23 '14 at 15:15
  • However, now these comments should point them in right way. btw you always tag my name wrong, I'm not getting notifications. ;) My name is Sriram Sakthivel, not Sirriam. :-D – Sriram Sakthivel Apr 23 '14 at 15:18
  • 1
    @SriramSakthivel, thanks for correction. And you have just educated me as what the `@` is doing when people reference another users name in comments.... I was unaware of what that was doing, if you can believe that... Thanks! Due to your comments, I will edit my answer to include note that NullzreferenceException should never be thrown by production code. – Charles Bretana Apr 23 '14 at 15:20
  • @CharlesBretana So its the getControlFromPosition? then how does this find the control for the co ordinates? My apolagies, i'm still learning so debugging is currently difficult to grasp. – Skippeh1234 Apr 23 '14 at 15:24
  • @CharlesBretana rather than including a note which can easily be overseen, why not changing the code so that it uses `Debug.Assert` instead? – Crono Apr 23 '14 at 15:28
  • @user3375561, Yes, it's the `getControlFromPosition()`. This is a method built in to the framework code for the `tableLayoutPanel1` control. How this works I am not sure. But your problem is getting the right values for the xLoc and yLoc variables. I can't be sure, but it might be how you are populating those variables. Methods that generate coordinate values can be relative to the entire screen, or to the window, or to the container control. When the values are relative to some other context then the one the `getControlFromPosition' expects them to be, you need to convert them. – Charles Bretana Apr 23 '14 at 15:32
  • @CharlesBretana the error occours even if i just hard code the location as 1,1. so surely if i am getting control of the position(1,1), it give some form of indication that this was the case. Could it be to do with the fact that it is more that the cell is being painted on event, yet is set as transparent through the winform generator, therefore defaulting it to be always transparent, therefore always null? – Skippeh1234 Apr 23 '14 at 15:45
  • @user, I am not sure, but how do you know there is a contained control inside `tableLayoutPanel1` at coordinates (1,1) ? If you can put a breakpoint on the code at the line above this, then examine the Controls collection of the container `tableLayoutPanel1`, and see what child controls are actually in it. – Charles Bretana Apr 23 '14 at 16:10
  • or, for illustration, change the code again, to `var control = gameBorder.FormInstance.tableLayoutPanel1.Controls[0];` to return the first control in the collection, and see what you get – Charles Bretana Apr 23 '14 at 16:11
0

The way you chain members and method results makes it hard to determine at a glance what causes the NullReferenceException to be thrown. FormInstance could be null if it's accessed before any gameBorder instances ever get created. Although unlikely, tableLayoutPanel could be null as well. The result of GetControlFromPosition method could very well be too, if no control is on the specified cell.

When you are encountering this kind of problem within this kind of code, the best thing to do is to decompose the calling chain. This way you will be able to quickly tell where the problem lies.

You can also make code assertions, like this:

var formInstance = gameBorder.FormInstance;
Debug.Assert(formInstance != null);
var controlAtPos = formInstance.tableLayoutPanel1.GetControlFromPosition(xloc, yloc);
Debug.Assert(controlAtPos != null);

controlAtPos.BackgroundImage = Properties.Resources.Image; // You may want to make some assertions on resolving your image instance too

The beauty of code assertions is that it's easy to exclude these from compiling into production code. By default, it's compiled in debug configuration and excluded in release configuration. This way you can benefit from the help it provides on debugging without worrying about the extra overhead in deployed code.

Keep this in mind, it will be useful if you ever face this issue again in the future.

Crono
  • 10,211
  • 6
  • 43
  • 75