遍历 bool list/array returns all false

Iterating over a bool list/array returns all false

我正在创建这个 windows 表单 c# 应用程序,我可以在其中从文件夹加载图像,通过单击它们的图像选择其中的几个,然后将它们复制到另一个文件夹。到目前为止一切似乎都很好,但现在我偶然发现了问题。我有 10 个布尔值,代表每个图像状态(selected 或未 selected)。

    public partial class Form1 : Form
{


    public bool selected1 = false;
    public bool selected2 = false;
    public bool selected3 = false;
    public bool selected4 = false;
    public bool selected5 = false;
    public bool selected6 = false;
    public bool selected7 = false;
    public bool selected8 = false;
    public bool selected9 = false;
    public bool selected10 = false;

这些是布尔值。 接下来我把它们放在列表中(我也测试了数组)

private List<bool> selectedBools = new List<bool>();

然后我将布尔值分配给 Public Form1():

中的列表
 selectedBools = new List<bool> { selected1, selected2, selected3, selected4, selected5, selected6, selected7, selected8, selected9, selected10 };

每个图像状态都由这段代码控制(每个picturebox_click都有相同的代码,但数字有所不同)

 private void pictureBox2_Click_1(object sender, EventArgs e)
    {


        if (selected1 == false)
        {

            pctBox1.Image = null;


            selected1 = true;
            pctBox1.BackColor = Color.Red;
        }
        else if (selected1 == true)
        {
            selected1 = false;
            pctBox1.BackColor = Color.White;
            try
            {
                pctBox1.Image = Image.FromFile(filePaths[0 + Page * 10]); // refresh image
            }
            catch
            {

            }

        }

    }

然后,当我按更改“页面”(它只是将每个图像移动 10)时,我再次将所有布尔值设置为 false。 问题是当我想将这些图像“上传”到文件夹时(只需将 select 复制到那里):

 private void UploadAllButton_Click(object sender, EventArgs e)
    {
        Console.WriteLine(selected1.ToString() + selected2 + selected3 + selected4 + selected5 + selected6 + selected7 + selected8 + selected9 + selected10);
        DialogResult result = MessageBox.Show(this, "Are you sure?", "Upload all", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
       
        if (result == DialogResult.Yes)
        {
          
            List<int> selectedBooleansIndexes = new List<int>();
            int i = 10;
            foreach (bool selected in selectedBools)
            {
                
                i--;
                Console.WriteLine(selected);

                Console.WriteLine(selectedBools[i]);
                if (selected == true)
                {
                    int index = selectedBools.FindIndex(a => a = true);
                    selectedBooleansIndexes.Add(index);
                    Console.WriteLine(selectedBooleansIndexes.Count);
                  }
                if (i == 0)
                {
                    Console.WriteLine(selected1.ToString() + selected2 + selected3 + selected4 + selected5 + selected6 + selected7 + selected8 + selected9 + selected10);
                    MessageBox.Show(this, selectedBooleansIndexes.Count.ToString(), "siur");
                }


                 

当我 select 一些图像时,它们的 select bool 变为 true。所以我想获取那些设置为 true 的索引并获取它们的索引,以便稍后我可以在复制文件时使用这些索引。问题是当我 运行 if (selected == true ) 所有这些似乎都是假的并且没有任何反应。我通过手动输入每个 bool 的控制台状态来检查,当我这样做时,它按预期工作。所以我的问题是,当我使用 foreach 循环时,每个 bool 状态都是假的,即使它不是(我检查了很多次,因为我认为某些东西在代码的不同位置覆盖了它们)。也许我遗漏了什么,但这很奇怪。

让我们简化您的代码以进行解释:

bool b1 = false;
bool b2 = false

到这里,一切都如你所料。 b1 和 b2 都是 false.

List<bool> l = new List<bool>(){b1, b2};

您现在有一个包含副本 b1b2 的列表。那是因为布尔值类型。

这是什么意思?如果您更改 b1[0] 而不是 随之更改。如果您更改 l[0]b1 而不是 随之更改。 b2l[1] 相同。他们完全独立。

现在让我们转向更大的问题。你肯定不想要副本,所以不要创建它们。

而不是

public bool selected1 = false;
[...]
public bool selected10 = false;

使用列表并通过索引访问条目。想想一个有 1000 张图像而不是 10 张图像的应用程序。你不会想声明 1000 个变量吧?

让我们创建一个包含 10 个布尔值的列表,用 false 初始化(因为这是它们的默认值):

List<bool> selected = new List<bool>(new bool[10]);

我们也把你所有的图片框放到一个列表中:

List<PictureBox> pictures = List<PictureBox>{pctBox1, ... pctBox10};

每当pctBox1改变时,pictures[0]也会随之改变。它不是副本。这会起作用,因为 PictureBox 是引用类型而不是值类型。

这样,您可以定义一个方法来完成所有事情:

private void DoSomething(int index)
{
        if (selected[index] == false)
        {    
            pictures[index].Image = null;        
            selected[index] = true;
            pictures[index].BackColor = Color.Red;
        }
        else  // DONE: if (selected[index] == true) is unnecessary, because true is the only option left
        {
            selected[index] = false;
            pictures[index].BackColor = Color.White;
            try
            {
                pictures[index].Image = Image.FromFile(filePaths[index + Page * 10]); // refresh image
            }
            catch { } // TODO: fix bad error handling
        }
 }

并且每个点击事件处理程序都变得像

一样简单
private void pictureBox2_Click_1(object sender, EventArgs e)
{
    DoSomething(0);  // change index only
}

我们通常会进一步简化 DoSomething() 方法。

private void DoSomething(int index)
{   
    selected[index] = !selected[index];  // Flip the value
    pictures[index].BackColor = selected[index]?Color.White:Color.Red;  // Choose the back color
    pictures[index].Image = null;  // Reset always, since it doesn't really matter
    if (selected[index])
    {
        try
        {
            pictures[index].Image = Image.FromFile(filePaths[index + Page * 10]); // refresh image
        }
        catch {} // TODO: still fix bad error handling
    }
}

我想今天就够了。人们可能也不会手动创建 10 个图片框,而是循环创建它们。