如何在不重复代码的情况下使用循环将多个图像加载到图片框中?

How to load multiple images into picture boxes using a loop without repeating code?

我想用for循环的递增来访问资源文件夹中不同的图片框和图片。我可以将其全部键入,如下所示,但我想对其进行更多“编程”。 (希望我的问题有意义)

private void btnUse19_Click(object sender, EventArgs e)
{
    string applicationDirectory = Application.ExecutablePath;

    //Using my student number as an index to get the file path of the application.
    string editedApplicationDirectory = applicationDirectory.Substring(0, applicationDirectory.IndexOf("19001700"));

    for (int i = 1; i <= 10; i++)
    {
        string spineNumber = i.ToString();

        string pbSpineNum = "pbSpine" + spineNumber;
        string picNameNum = "Spine " + spineNumber + ".png";

        //this is what im trying to do but does not work
        pbSpineNum.Image = Image.FromFile(editedApplicationDirectory + "19001700" + "\Resources\"+picNameNum);
    }

    //Dont want to have to do this
    pbSpine1.Image = Image.FromFile(editedApplicationDirectory + "19001700" + "\Resources\Spine 1.png");
    pbSpine2.Image = Image.FromFile(editedApplicationDirectory + "19001700" + "\Resources\Spine 2.png");
    pbSpine3.Image = Image.FromFile(editedApplicationDirectory + "19001700" + "\Resources\Spine 3.png");
    pbSpine4.Image = Image.FromFile(editedApplicationDirectory + "19001700" + "\Resources\Spine 4.png");
    pbSpine5.Image = Image.FromFile(editedApplicationDirectory + "19001700" + "\Resources\Spine 5.png");
    pbSpine6.Image = Image.FromFile(editedApplicationDirectory + "19001700" + "\Resources\Spine 6.png");
    pbSpine7.Image = Image.FromFile(editedApplicationDirectory + "19001700" + "\Resources\Spine 7.png");
    pbSpine8.Image = Image.FromFile(editedApplicationDirectory + "19001700" + "\Resources\Spine 8.png");
    pbSpine9.Image = Image.FromFile(editedApplicationDirectory + "19001700" + "\Resources\Spine 9.png");
    pbSpine10.Image = Image.FromFile(editedApplicationDirectory + "19001700" + "\Resources\Spine 10.png");
}

您可以使用图片框列表和计数器来重构并将所有内容减少到循环中移动的一行:

using System.IO;
using System.Collections.Generic;

var pictureBoxes = new List<PictureBox>();

string pathExe = Path.GetDirectoryName(Application.ExecutablePath);
string pathImagesPattern = Path.Combine(pathExe, "Resources", "Spine {0}.png");

for ( int index = 1; index <= 10; index++ )
{
  var pictureBox = new PictureBox();
  string pathImage = string.Format(pathImagesPattern, index);
  pictureBox.Image = Image.FromFile(pathImage);
  pictureBoxes.Add(pictureBox);
}

我把名字改得更通俗易懂,路径也改成了我好像理解你在做什么。

现在您可以使用列表来处理项目,例如将它们添加到面板中,或表单:

MyPanel.Controls.AddRange(pictureBoxes.ToArray());

您可以像这样访问它们:

pictureBoxes[0].Location = ...

但是您应该使用特定的计算变量来初始化循环中的每个控件以进行渲染:

pictureBox.Location = new Point(posX, posY);

如果您打算在方法之外使用它,您可能需要将此列表提升为 class 数据成员:

private List<PictureBox> PictureBoxes = new List<PictureBox>();

另一个使代码更简洁的改进是在循环本身中使用常量或变量而不是文字:

private int PictureBoxesCount = 10;

PictureBoxes.Clear();
for ( int index = 1; index <= PictureBoxesCount; index++ )

如果这个数字是固定的,你可以使用 const 和固定数组来代替 List:

const private int PictureBoxCount = 10;

private PictureBox[] PictureBoxes = new PictureBox[PictureBoxCount];

for ( int index = 0; index < PictureBoxes.Length; index++ )
{
  string pathImage = string.Format(pathImagesPattern, index);
  PictureBoxes[index] = new PictureBox();
  PictureBoxes[index].Image = Image.FromFile(pathImage);
}

如果图片框是使用 Visual Studio 表单设计器创建的并且已经创建,您可以简单地使用这个预先分配的数组:

  PictureBoxes = Controls.OfType<PictureBox>()
                         .Where(p => p.Name.StartsWith("pbSpine"))
                         .OrderBy(p => p.Name.Length)
                         .ThenBy(p => p.Name)
                         .ToArray();

  for ( int index = 0; index < PictureBoxes.Length; index++ )
  {
    string pathImage = string.Format(pathImagesPattern, index);
    PictureBoxes[index].Image = Image.FromFile(pathImage);
  }

但与完全动态版本不同的是,这里我们可能会遇到控件索引和图像索引之间的匹配问题。

因此,我不建议将它与已经放置在表单上的控件一起使用,除非我们知道我们在做什么并且我们以可靠的方式控制流程。