0

我正在设计的程序通过获取图像的文件名来制作图像,在 cdb 中搜索该名称,然后使用该数据库项中的数据制作图片。所有这些都有效。我现在想要做的是添加一个进度条,因为如果您要处理大量图片,可能需要一段时间,因此进度条将有助于跟踪它。这是我正在使用的代码,但进度条中的进度直到最后我想避免使用后台工作者(如果可以的话)才前进。

   private void button5_Click(object sender, EventArgs e)
    {
        if (folderBrowserDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
        {
            string folder = folderBrowserDialog1.SelectedPath;
            DirectoryInfo dinfo = new DirectoryInfo(folderBrowserDialog1.SelectedPath);
            FileInfo[] Files = dinfo.GetFiles("*.jpg");
            int count = Files.Length;
            int current = 0;
            foreach (FileInfo file in Files)
            {
                string path = Path.GetFileNameWithoutExtension(file.Name);
                int cardid = Convert.ToInt32(path);
                if (Program.CardData.ContainsKey(cardid))
                {
                    DevPro_CardManager.cardmaker.IMG = LoadBitmap(folderBrowserDialog1.SelectedPath + "//" + file.Name);
                    string lev = Program.CardData[cardid].Level.ToString();
                    comboBox2.SelectedItem = lev;
                    string att = Program.CardData[cardid].Attribute.ToString();
                    if (att == "1")
                    {
                        att = "earth";
                    }
                    else if (att == "2")
                    {
                        att = "water";
                    }
                    else if (att == "4")
                    {
                        att = "fire";
                    }
                    else if (att == "8")
                    {
                        att = "wind";
                    }
                    else if (att == "16")
                    {
                        att = "light";
                    }
                    else if (att == "32")
                    {
                        att = "dark";
                    }
                    else if (att == "64")
                    {
                        att = "divine";
                    }
                    comboBox1.SelectedItem = att;
                    if (Program.CardData[cardid].Atk.ToString() == "-2")
                    {
                        textBox2.Text = "????";
                    }
                    else
                    {
                        textBox2.Text = Program.CardData[cardid].Atk.ToString();
                    }
                    if (Program.CardData[cardid].Def.ToString() == "-2")
                    {
                        textBox1.Text = "????";
                    }
                    else
                    {
                        textBox1.Text = Program.CardData[cardid].Def.ToString();
                    }
                    string ctp = Program.CardData[cardid].Type.ToString();
                    if (ctp == "2" || ctp == "130" || ctp == "65538" || ctp == "131074" || ctp == "262146" || ctp == "524290")
                    {
                        ctp = "spell";
                    }
                    else if (ctp == "4" || ctp == "1048580" || ctp == "131076")
                    {
                        ctp = "trap";
                    }
                    else if (ctp == "129" || ctp == "161")
                    {
                        ctp = "ritual";
                    }
                    else if (ctp == "65" || ctp == "97")
                    {
                        ctp = "fusion";
                    }
                    else if (ctp == "8193" || ctp == "8225" || ctp == "12321")
                    {
                        ctp = "synchro";
                    }
                    else if (ctp == "8388609" || ctp == "8388641")
                    {
                        ctp = "xyz";
                    }
                    else if (ctp == "33" || ctp == "545" || ctp == "1057" || ctp == "2081" || ctp == "4129" || ctp == "4194337")
                    {
                        ctp = "effect";
                    }
                    else if (ctp == "17" || ctp == "4113")
                    {
                        ctp = "normal";
                    }
                    else if (ctp == "16401")
                    {
                        ctp = "token";
                    }
                    comboBox3.SelectedItem = ctp;
                    GenerateCard();
                    ImageResizer.CropImage(361, 523, pictureBox1.Image, @"anime cards\" + Path.GetFileName(file.Name));
                    int cardcount = +1;
                    label8.Text = cardcount.ToString();
                }      
                current++;
                progressBar1.Value = current / count;
            }
        }
    }
4

3 回答 3

5

我更喜欢 BackgroundWorker 而不是 DoEvents。这是处理真正应该是后台任务的更清洁的方法。

由于泛型,调用并不像 MSDN 上描述的那么复杂。

ControlName.Invoke(new Action(() => { /* UI update commands */ }));

更新:添加示例

这是一个成功的 BackgroundWorker 的非常基本的示例。有几点需要注意。转换为浮点以正确计算百分比,以及使用 for 循环而不是 foreach,因此计数器是固有的。DoWork 事件处理程序中对表单对象的唯一调用使用this.Invoke通用委托来安全地调用 UI 对象进行更新,最后通过 eventArgs 将文件列表传递给 BackgroundWorker。

public partial class Form1 : Form
{
    BackgroundWorker fileParser;

    public Form1()
    {
        InitializeComponent();

        fileParser = new BackgroundWorker();
        fileParser.WorkerReportsProgress = true;
        fileParser.DoWork += new DoWorkEventHandler(fileParser_DoWork);
        fileParser.ProgressChanged += new ProgressChangedEventHandler(fileParser_ProgressChanged);

        // Emulating the FolderBrowserDialog results here
        List<String> fileNames = new List<String> { "File 1", "File 2", "File 3", "File 4", "File 5" };
        fileParser.RunWorkerAsync(fileNames);
    }

    void fileParser_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        // Update progress bar here
        tbOutput.Text += e.ProgressPercentage.ToString() + "% | ";
    }

    void fileParser_DoWork(object sender, DoWorkEventArgs e)
    {
        List<String> fileNames = e.Argument as List<String>;

        for (int i = 0; i < fileNames.Count; i++)
        {
            // Do intense work here
            Thread.Sleep(2000);
            this.Invoke(new Action(() => { tbOutput.Text += fileNames[i] + ": "; }));
            float completePercent = ((float)(i + 1) / (float)fileNames.Count) * 100;

            // Send event to update progress bar here
            fileParser.ReportProgress(Convert.ToInt32(completePercent));
        }
    }        
}
于 2013-08-31T04:42:13.513 回答
1

进度条值更改后,只需在下面写下

progressBar1.Value = current / count;
Application.DoEvents();

Application.DoEvents() 会将更改应用到 UI 并刷新它,以便您能够看到 UI 的新更改。

于 2013-08-31T04:41:28.080 回答
1

只是你看不到它,但它已更新。

值应该在 0 到 100 之间。

尝试:

progressBar1.Value = (current / count) * 100;
于 2013-08-31T05:10:00.353 回答