0

I'm a Rookie and I'm having some Problems. Google hasn't helped me as much as I wanted to because I seriously hate asking and taking time of others for something, but since I'm stuck here for a couple of hours, I'm going to ask.

First, I have a xaml.codesource that is working perfectly. I've engulfed about 30 TextBoxes in a StackPanel, named the StackPanel 'ScoreList' and added a MouseLeftButtonDown_Event {ScoreList.AddHandler(FrameworkElement.MouseLeftButtonDownEvent, new MouseButtonEventHandler(ScoreList_Click), true); } on it so that once I click a TextBox, it's going to call that Event.

Everything works so far as much as that the TextBoxes (Although you might want to shake your head about my choice of using TextBoxes instead of Buttons) Show various scores depending on a RandomList which isn't important now.

Now in the Event ScoreList_Click..

private void ScoreList_Click(object sender, MouseButtonEventArgs e)
{
    TextBox x = e.OriginalSource as TextBox;

    if (x != null)
    {
        MessageBox.Show("Don't try this at home Kiddo");
    }

    if (x.Text == "1" || x.Text == "2" || x.Text == "3" || x.Text == "4")
    {
        x.Text = "10";
        x.IsEnabled = false;    
    }
}

I have currently following Problems:

  • When I try to check TextBox x for null, it throws a NullReferenceException at me. Even without the check, it throws a NullReferenceException.

  • I am searching for ideas or a way how to completely lock away a TextBox once clicked. What I mean is that since my TextBoxes have a Click_Event on them, that a second Click won't call the Event again. (Unsubscribe won't work because reasons. No, really. Reasons. Since StackPanel is bound to the Event, I can't unsubscribe a whole Event when all I want is to 'unsubscribe to a single TextBox inside StackPanel'.

Sorry for troubling you guys. I might have given too much thought in it as I want to reduce my code heavily from like 80 lines code to 5 with my idea.

Joe
  • 6,773
  • 2
  • 47
  • 81
Half Steps
  • 31
  • 3
  • Use a break point and watch all of your variables. This is common debugging practice that will help fix this. – Felix Castor May 12 '16 at 10:30
  • 1
    What line does the exception occur, exactly? Have you stepped through with a debugger and checked if any of the variables are null when the exception occurs. – Joe May 12 '16 at 10:30
  • If you read your code, what will happen when x is null? it will go to the second if statement and try to access `x.Text` - but x is null so you get a nullreferenceexception. You're also describing other issues. Could you try to keep it to one question instead? I'm not sure how this question might be reasonably answered. – default May 12 '16 at 11:12

1 Answers1

0

First thing to do is to drop a breakpoint in and step through line by line. What line does the exception even happen on? That would be useful to know so we can say what's wrong.

In the debugger you can hover over a variable and it will say what it is, whether it's null, and you can even investigate it's properties.

I see one possible problems with your code:

    if (x != null)
    {
        MessageBox.Show("Don't try this at home Kiddo");
    }

You are checking that x is not null here, but inside you're not using it. Are you trying to perform a null check? I'm not sure if this message is supposed to be a warning, or just part of your code etc. I'd expect to see something like:

    if (x == null)
    {
        MessageBox.Show("Null text box");
        return;
    }

if you are performing a null check. Notice that it calls return; so the method exists without continuing.

That, or you're only wanting the user to see the message if they've clicked on the text box, in which case fine, except you are actually doing no null checking at all on the code where a null exception might occur (accessing x.something) here:

    if (x.Text == "1" || x.Text == "2" || x.Text == "3" || x.Text == "4")
    {
        x.Text = "10";
        x.IsEnabled = false;
    }

It should be structured like this:

    TextBox x = e.OriginalSource as TextBox;

    if (x != null)
    {
        MessageBox.Show("User clicked textbox message");


        //this is within the not null check
        if (x.Text == "1" || x.Text == "2" || x.Text == "3" || x.Text == "4")
        {
            x.Text = "10";
            x.IsEnabled = false;

        }
    }

or this:

    TextBox x = e.OriginalSource as TextBox;

    if (x == null)
    {
        MessageBox.Show("User has not clicked text box message");
        //exit method
        return;
    }

    //this is only reached if x is not null
    if (x.Text == "1" || x.Text == "2" || x.Text == "3" || x.Text == "4")
    {
        x.Text = "10";
        x.IsEnabled = false;
    }

As for it only doing it for one click per text box, there's a number of ways you could do this. First thing that occurs to me is to store the clicked items in something like a list or dictionary, and check if it's present before continuing.

List<TextBox> alreadyClickedTextBoxes = new List<TextBox>();

ScoreList_Click(object sender, MouseButtonEventArgs e) {

    TextBox x = e.OriginalSource as TextBox;

    //check this is a text box, and has not been clicked
    if (x != null && !alreadyClickedTextBoxes.Contains(x))
    {
        MessageBox.Show("Don't try this at home Kiddo");

        if (x.Text == "1" || x.Text == "2" || x.Text == "3" || x.Text == "4")
        {
            x.Text = "10";
            x.IsEnabled = false;
        }
        //we don't want to click this again
        alreadyClickedTextBoxes.Add(x);
    }
}
Joe
  • 6,773
  • 2
  • 47
  • 81
  • Thanks alot. But the Problem it seemed was that I used OriginalSource instead of Source and it seems that was the only reason why null came out. Despite that, your comment was helpful in that I wrote my null checker completely wrong. Thank you. Oh and the part for 'one click per text box' seems alright/perfect, I'll use that! Thanks again. (Can't vote because of lack of Reputation) – Half Steps May 12 '16 at 11:43