Прогресс Бар помощь - PullRequest
1 голос
/ 22 мая 2009

Я очень плохо знаком с программированием и до сих пор неплохо справляюсь. Но индикаторы прогресса все еще смущают меня. К сожалению, в Интернете есть много разных примеров, чтобы я мог что-то из них извлечь. Некоторые говорят, что использовать фонового работника некоторые не могут, и т.д. Ниже у меня есть то, что я думаю, должно работать, но не работает. Предполагается, что она просто отображает индикатор при копировании файла из одной папки в другую. Любая помощь приветствуется.

Спасибо.

        private void btnCopyFiles_Click(object sender, EventArgs e)
    {
        string folder1 = @"c:\folder1\";
        string folder2 = @"c:\folder2\";

        DirectoryInfo di = new DirectoryInfo(folder1);
        FileInfo[] filelist = di.GetFiles("*.*");
        int count = di.GetFiles("*.*").Length;

        this.progressBar1 = new System.Windows.Forms.ProgressBar();
        progressBar1.Maximum = count;
        progressBar1.Minimum = 0;
        progressBar1.Step = 1;

        foreach (FileInfo file in filelist)
        {
            try
            {
                this.Cursor = Cursors.WaitCursor;
                File.Copy(folder1 + @"\" + file.Name, folder2 + @"\" + file.Name, true);
                progressBar1.PerformStep();
                this.Cursor = Cursors.Default;
            }
            catch (Exception error)
            {
                MessageBox.Show("Error: " + error);
            }
        }
    }

Ответы [ 6 ]

4 голосов
/ 22 мая 2009

Я предполагаю, что вы используете Visual Studio и добавили элемент управления ProgressBar, перетаскивая его на форму. Если это правильно, проблема может быть в следующей строке:

this.progressBar1 = new System.Windows.Forms.ProgressBar();

Повторно создав элемент управления, вы теряете его ссылку на форму. Просто удалите или прокомментируйте эту строку и попробуйте снова.

2 голосов
/ 22 мая 2009

Сначала создайте структуру для хранения аргументов в BackgroundWorker, которые будут переданы в DoWorkEventArgs.

public struct CopyStruct
{
    public string sourceDir;
    public string destDir;
}

Затем сделайте что-то вроде этого:

private void btnCopyFiles_Click(object sender, EventArgs e)
{
    InitializeBackgroundWorker();

    CopyStruct copyStruct = new CopyStruct
    {
        sourceDir = @"C:\folder1\",
        destDir = @"C:\folder2\"
    };

    backgroundWorker.RunWorkerAsync(copyStruct);
}

private void InitializeBackgroundWorker()
{
    backgroundWorker.WorkerReportsProgress = true;
    backgroundWorker.DoWork += backgroundWorker_DoWork;
    backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted;
    backgroundWorker.ProgressChanged += backgroundWorker_ProgressChanged;
}

private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    progressBar.Value = e.ProgressPercentage;
}

private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    // do something when finished
}

private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
    BackgroundWorker worker = (BackgroundWorker) sender;
    CopyStruct copyStruct = (CopyStruct) e.Argument;

    DirectoryInfo di = new DirectoryInfo(copyStruct.sourceDir);
    FileInfo[] filelist = di.GetFiles("*.*");

    int numFiles = filelist.Length;

    for (int i = 0; i < numFiles; i++)
    {
        FileInfo file = filelist[i];

        File.Copy(Path.Combine(copyStruct.sourceDir, file.Name), Path.Combine(copyStruct.destDir, file.Name), true);

        // This line updates the progress bar
        worker.ReportProgress((int) ((float) i/numFiles*100));
    }
}

Это почти не содержит проверки ошибок, поэтому вам придется добавить ее, но она работает с несколькими тестовыми каталогами в моей системе.

2 голосов
/ 22 мая 2009

В целом проблема заключается в том, что ваш код продолжает выполняться, не позволяя форме перерисовывать себя так, как нужно. Ваш лучший и самый быстрый путь - использовать BackgroundWorker для фактического выполнения вашей операции, используя ее события для обновления прогресса. При этом обновление индикатора выполнения выполняется в потоке пользовательского интерфейса, а пользовательский интерфейс обновляется, ваши файловые операции выполняются за сценой.

1 голос
/ 22 мая 2009

Поскольку вы новичок в программировании, начните с этого.

Добавить

    Application.DoEvents();

после

    progressBar1.PerformStep();

Это должно заставить ваше приложение работать на данный момент. В конечном итоге вы захотите перенести процесс копирования в поток / фоновый рабочий. Но, не зная ваших способностей, Application.DoEvents (), вероятно, самое простое, но не предпочтительное исправление.

1 голос
/ 22 мая 2009

Чтобы индикатор выполнения обновлялся в вашем пользовательском интерфейсе, процесс, работающий с чем-то, должен выполняться в другом потоке (в противном случае он блокирует поток пользовательского интерфейса, и пользовательский интерфейс не будет обновляться). BackgroundWorker - хороший кандидат для этого.

Выполните цикл копирования файла в событии DoWork фонового работника и вызовите метод BackgroundWorker.ReportProgress , чтобы, в общем, сообщить о прогрессе. В обработчике события ProgressChanged вы можете установить значение в элементе управления ProgressBar. Вы запускаете процесс, вызывая метод RunWorkerAsync компонента BackgroundWorker.

0 голосов
/ 22 мая 2009

вы пробовали progressbar1.Increment (x) где x - количество переданных файлов?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...