【问题标题】:Using tags with picturebox in Visual Studio在 Visual Studio 中使用带有图片框的标签
【发布时间】:2017-08-29 21:45:20
【问题描述】:

我正在练习 C# 编程,并且正在学习我在网上找到的教程。我对 Visual Studio 女士产生了兴趣,目前一直在自学。我已经对教程进行了自己的编辑,但尽可能接近教程。一切似乎都很好,除了代码中有一部分我无论做什么或研究都无法弄清楚。在教程中,它让我创建了 30 个图片框。每个图片框都标有一个单词名称,例如块或砖块或您选择的任何名称。我认为这是为了更容易一次使用所有图片框而不是一次执行一个 if/else 语句。我明白只说“如果图片框有标签“砖块”然后做 XYZ 会更省时间。 无论如何,我按照代码到了 T 但 visualbasic 说

"可能是非预期的引用比较;要进行值比较,请将左侧转换为类型 'string'

这是给我的代码部分

foreach (Control x in this.Controls)
        {
            if (x is PictureBox && x.Tag == "blockies")
            {
                if (pBall.Bounds.IntersectsWith(x.Bounds))
                {
                    this.Controls.Remove(x);
                    pBally = -pBally;
                    score++;
                }
            }
        }

它有一条从 x.Tag 到 blockies 的绿色波浪线” 谢谢你的帮助。 附言。窗体

【问题讨论】:

  • but visualbasic is saying VB 代码在哪里?
  • 上面的引号中的内容差不多。
  • 我看到了,但是和VB没有任何关系。它是 c#
  • 对不起,我的意思是这只是使用 VS 2017 的 Windows Form C#

标签: c# visual-studio-2017


【解决方案1】:

我发现使用 Linq 更具可读性。

解决比较警告问题和在枚举集合时从集合中删除元素的问题

foreach(var pb in this.Controls
                    .OfType<PictureBox>()
                    .Where(x => (string)x.Tag == "blockies")
                    .Where(x => pBall.Bounds.IntersectsWith(x.Bounds))
                    .ToList())
{
    this.Controls.Remove(pb);
}

【讨论】:

  • 您好,感谢您的回复!不幸的是,当我使用此代码时,图片框立即开始消失。我应该在一开始就说明我正在用这种类型的代码制作一个方块游戏。我还有什么需要解决的吗?谢谢
  • 当我添加您的代码时,“球”不再反弹。
  • @Razgr1z 此代码类似于您发布的问题并修复了它。你现在问不同的东西,我不知道你的代码,也不知道你是否有逻辑错误。
【解决方案2】:

那是因为Tag 不是字符串。你需要改为x.Tag.ToString() == "blockies"

foreach (Control x in this.Controls)
{
    if (x is PictureBox && x.Tag != null && x.Tag.ToString() == "blockies")
    {
        if (pBall.Bounds.IntersectsWith(x.Bounds))
        {
            this.Controls.Remove(x);
            pBally = -pBally;
            score++;
        }
    }
}

【讨论】:

  • 如果我这样做,我会得到 System.NullReferenceException: 'Object reference not set to an instance of an object。' System.Windows.Forms.Control.Tag.get 返回 null。
  • @Razgr1z 在调用ToString() 之前检查x.Tag != null。发生这种情况时,您的标签为空。我已经编辑了我的答案以反映这一点
【解决方案3】:

如果你打开Control.Tag,你会看到它的定义。

public object Tag { get; set; }

您正在尝试将对象与字符串进行比较,因此会显示此错误消息。

你应该做的是:

if (x is PictureBox && x.Tag.ToString() == "blockies")

还有一点你应该尽量避免箭头代码结构,它真的很难阅读:

    foreach (Control x in this.Controls)
    {
        if (!(x is PictureBox))
           continue;

        //this is needed if you want to use some specific property of the PictureBox.
        PictureBox ctl = (PictureBox)x;

        if(ctl.Tag.ToString() != "blockies")
            continue;

        if (!pBall.Bounds.IntersectsWith(ctl.Bounds))
             continue;

         //Also this line will create you a problem, because you will change the Control collection 
         //when you try to enumerate it. This should throw you an exception. Better make the control not visible.
         //this.Controls.Remove(x);

         x.Visible = false;

         pBally = -pBally;
         score++;
    }

在这种情况下,您的代码具有更好的可读性。

【讨论】:

  • 不是我的反对票,而是您的三重 continues 可能不符合每个人的口味。
猜你喜欢
  • 1970-01-01
  • 2014-07-29
  • 1970-01-01
  • 2014-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-16
  • 2016-05-20
相关资源
最近更新 更多