NullReferenceException - StackBox上的问题,TextBox作为OriginalSource,TextBox上的自定义MouseLeftButtonDown_Event

时间:2016-05-12 09:55:23

标签: c# wpf

我是新秀,我遇到了一些问题。 谷歌没有像我想的那样帮助我,因为我非常讨厌要求别人花时间做些什么,但是因为我被困在这里几个小时,我会问

首先,我有一个完美的xaml.codesource。 我在StackPanel中吞噬了大约30个TextBox,名为StackPanel' ScoreList'并添加了MouseLeftButtonDown_Event {ScoreList.AddHandler(FrameworkElement.MouseLeftButtonDownEvent,new MouseButtonEventHandler(ScoreList_Click),true); 在它上面,这样一旦我点击一个TextBox,它就会调用该事件。

所有内容都与TextBoxes一样有效(尽管你可能想要动摇我选择使用TextBoxes而不是Buttons)根据RandomList显示各种分数,这对于现在来说并不重要。

现在在事件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;    
    }
}

我目前遇到以下问题:

  • 当我尝试将TextBox x检查为null时,它会向我抛出NullReferenceException。即使没有检查,它也会抛出NullReferenceException。

  • 我正在搜索想法或如何在点击后完全锁定TextBox的方法。我的意思是,因为我的TextBoxes上有一个Click_Event,所以第二次点击不会再次调用该事件。 (取消订阅因为理由而赢了工作。不,真的。原因。由于StackPanel与事件绑定,我无法取消订阅整个事件,只要我想要的是取消订阅单个TextBox在StackPanel内部#39;。

抱歉让你们烦恼。我可能已经考虑了太多,因为我希望将我的代码从80行代码大量减少到5代码。

1 个答案:

答案 0 :(得分:0)

首先要做的是删除一个断点并逐行执行。异常甚至发生在什么线上?这有助于了解我们可以说出错的原因。

在调试器中,您可以将鼠标悬停在某个变量上,它会说明它是什么,它是否为null,您甚至可以调查它的属性。

我发现您的代码存在一个可能的问题:

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

您正在检查x在此处不为空,但在您内部并未使用它。你想尝试进行空检查吗?我不确定此消息是应该是警告,还是仅仅是您的代码的一部分等等。我希望看到类似的内容:

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

如果您正在执行空检查。请注意,它调用return;,因此该方法不会继续存在。

那,或者你只是想让用户看到消息,如果他们点击了文本框,在这种情况下很好,除了你实际上没有对代码进行空检查这里可能会发生一个null异常(访问x.something):

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

它的结构应该是这样的:

    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;

        }
    }

或者这个:

    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;
    }

至于每个文本框只进行一次点击,有很多方法可以做到这一点。我遇到的第一件事就是将点击的项目存储在列表或字典之类的内容中,并在继续之前检查它是否存在。

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);
    }
}