【问题标题】:NullReferenceException was unhandled in C#NullReferenceException 在 C# 中未处理
【发布时间】:2010-12-05 09:51:28
【问题描述】:

我在我评论的那一行中发现了这个错误,有什么问题?

private void pictureBox34_Click(object sender, EventArgs e)
{
    if (pictureBox34.Image == chess9.Properties.Resources.siyahsah2)
    {
        f();
    }
}

public void picarray()
{
    pic[0, 0] = pictureBox54;
    pic[0, 1] = pictureBox64;
    pic[0, 2] = pictureBox48;
    pic[0, 3] = pictureBox42;
    pic[0, 4] = pictureBox34;
    pic[0, 5] = pictureBox26;
    pic[0, 6] = pictureBox18;
    pic[0, 7] = pictureBox8;
    pic[1, 0] = pictureBox1;
    pic[1, 1] = pictureBox2;
    pic[1, 2] = pictureBox3;
    pic[1, 3] = pictureBox4;
    ...
}

public void f()
{
    // int i = 0, j = 0;
    int x = 3;
    int y = 3;

    for (int i = 1; i < x; i++)
    {
        for (int j = 1; j < y; j++)
        {
            pic[i, j] = new PictureBox();
            // pic[i, j] = pic[i + 1, j + 1];
            pic[i, j].Image = chess9.Properties.Resources.siyahsah2;
        }
    }
}

【问题讨论】:

  • 查看图片的路径...
  • 你的代码太疯狂了。你为什么要为同一个数组条目分配 3 次。前两个任务是无操作的。而你的picarray 功能很可悲。为什么要使用 64 个预先创建的图片框,而不是在运行时循环创建它们?
  • 您的路径是相对于工作目录的,而不是相对于应用程序目录的。每当您的程序使用与应用程序目录不同的工作目录启动时,这将导致意外错误。
  • @CodeInChaos:同意,但要注意一点:Winforms 不会自动 Dispose PictureBoxes 内的图像。因此,每个图像只有一个预先创建的实例比在需要时创建它们更有优势,因为您不会很快用完窗口/GDI 句柄(因为您最终会创建不那么新鲜的PictureBox 实例)。但这当然不能解决真正的问题,(当然是要正确处理图像)。
  • 我会在启动时创建 64 个图片框到一个数组中。每件一个图像到另一个数组中。然后我只需将图像数组中的图像分配给所需的图片框。 (或者只是使用单个图片框编写渲染代码,但这超出了 OP 的范围)。

标签: c# winforms exception-handling


【解决方案1】:

我碰巧看了你之前的问题,所以如果我理解正确的话,这是一个国际象棋游戏的实现。

建议您对设计进行一些更改,而不是尝试修复此代码中的异常。

主要变化:将游戏板状态的表示与 UI 层分开。 如果我理解正确,您使用的是一组 PictureBox 对象来表示板上的棋子。如果您编写代表棋盘、棋子及其所有动作的类,然后编写可以在窗口中显示这些类并通过 UI 接收用户命令的单独代码,您可能会更好。

当您通过操作 UI 对象来实现棋子移动和棋盘更新时,您必然会犯更多错误并花费更多时间进行调试。

希望对你有帮助……

【讨论】:

  • 我知道这对于编写一个完整的国际象棋游戏很有用,但我为国际象棋游戏编写代码,它有 3 个棋子,一侧是国王和王后,另一侧只有国王,那一侧必须配对动作少的国王
  • 无论您正在开发什么游戏,将“游戏世界”与图形表示和 UI 分开总是一个好主意。即使游戏有一个只有几块棋子的简化棋盘。
  • 是的,你说得对,我会将游戏板状态与 UI 分开,但我只是想纠正这个王牌的移动,看看它是否有效,然后我会这样做。非常感谢你的建议
【解决方案2】:
  • 确保指示的文件确实存在。此外,如果您在 Windows 系统上运行它,最好将文件路径中的 / 更改为 \\(或 \ 中的 @"..." 字符串)。 (虽然这不应该是您的问题的原因。)

    ... = Image.FromFile( @"pic\siyahsah2.jpg" );

  • 确保索引 ij 正确。您的for 循环表明它们将是12 的任意组合。

此外,在您的 for 循环中:

pic[i, j] = new PictureBox();            //  <-- will get overwritten by (*)
pic[i, j] = pic[i + 1, j + 1];           //  <-- will get overwritten by (*)
pic[i, j] = new PictureBox();            //  <-- (*)
pic[i, j].Image = Image.FromFile(...);

即可以删除前两行。

【讨论】:

  • 谢谢,我按照你说的做了,现在它没有给出任何错误,但它没有任何动作
  • 对不起先生,我没有说清楚,我是指国际象棋中国王棋子的动作,好的我再问一个问题,谢谢
  • @arash:不用担心。我承认我确实知道你在谈论游戏人物的移动——只要把上面的评论作为一个线索,混合不同的问题会使在这里回答和投票变得如此困难。 ;)
【解决方案3】:

我不知道你为什么要把它弄得这么复杂,但是假设骑士在picturebox34 或者换句话说在pic[0, 4] 并且你想将它向右移动并因此结束在pic[2, 3] 上,那无非就是这样做

// Move knight image from 0,4 to 2, 3
pic[2, 3].Image = pic[0, 4].Image;

// Make old knight position empty
pic[0, 4].Image = null;

我不知道你为什么要做for循环之类的......

【讨论】:

  • 谢谢,我知道这一点,但我不想手动执行此操作,它应该自动执行,例如现在当国王来到 pic[2,3] 时它应该自动找到它的方式我点击王牌就可以走了,如果你不明白请告诉我更多的解释,谢谢
  • 一个骑士有 8 个可能的动作,你如何决定它应该采取哪一个?
  • 它的国王不是骑士,是的,当我点击国王图片框时,它有 8 个可能的动作我想要它显示国王的可能动作,怎么样?然后我想为黑色实现皇后和国王团队,以及他们的动作,然后我会决定应该采取哪个动作,正如我所说,它只有棋子,一侧是国王和王后,另一侧是国王,王后和国王应该在更少的动作中与国王交配。什么你建议我吗?非常感谢
  • 只使用PictureBoxes有点复杂,如果你按照Ran的建议去做会容易得多。如果您不知道该怎么做,我建议您至少尝试针对您在此过程中遇到的问题提出单独的问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多