Программа переименования изображений на C # /.NET

#c# #.net #visual-studio

#c# #.net #visual-studio

Вопрос:

Я работаю над программой .NET, которая предназначена для перебора выбранного каталога и позволяет переименовывать файлы изображений после отображения изображений. По моему коду я чувствую, что около 98% программы выполнено, но я использовал while цикл для ожидания нажатия кнопки, чтобы разрешить переименование файла изображения. Тем не менее, while цикл замораживает программу каждый раз while , когда цикл повторяется.

Как я могу system("pause"); , например, в C while приостановить цикл без замораживания программы и создания бесконечного цикла или как я могу while автоматически приостановить цикл до нажатия кнопки?

Вот лакомый кусочек кода для цикла:

 paused = true;
bool X = false;
label2.Text = "please choose a file name and press next";
//while statement
while (X == false)
{
    if (paused == false)
    {
        //Renames filename
        string newFileName = filenameTextbox.Text;

        //Adds filename to selected directory where user wishes to send file to
        string outputFile = destinationDirectory   "\"   intCounter   fileNameOfficial;

        //Pause statement to move to next operand..

        //Copies post iterated file to selected directory
        File.Copy(inputFile, outputFile, true);
        X = true;
    }
}
  

Ниже приведен полный код.

 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Collections;


namespace recursionBitches
{

    public partial class fileSorter : Form
    {
        bool paused = true;
        public fileSorter()
        {
            InitializeComponent();
        }

        private void browseFrom_Click(object sender, EventArgs e)
        {
            //Warning dialouge for selecting a large file.
            MessageBox.Show("Warning, before selecting the origination file, it is important to note that choosing too large of a directory (for example, my documents or 'C://') more than likely will cause this program to freeze. ");
            MessageBox.Show("You have been warned");
            //Choose the originating dir path. This dir path is to be later sorted using recursion.
            //Once the originating dir path is chosen, it is added to the label above the button.
            if (fromBrowse.ShowDialog(
                ) == DialogResult.OK)
            {
                this.originationLabel.Text = fromBrowse.SelectedPath;
            }
        }


        private void browseTo_Click(object sender, EventArgs e)
        {
            //Choose the send to dir path. This dir path is to later have the files that are sorted sent to it.
            //Once the to dir path is chosen, it is added to the label above the button.
            if (toBrowse.ShowDialog(
               ) == DialogResult.OK)
            {
                this.sendingLabel.Text = toBrowse.SelectedPath;
            }
        }


        private void sortButton_Click(object sender, EventArgs e)
        {
            string fileExtension = "*"   fileExtensionTextbox.Text;
            //Check from path to ensure they are set to a user defined path.
            int intCounter = 1;
            if (originationLabel.Text != "From")
            {
                //Check to path to ensure it is set to a user defined path.
                if (sendingLabel.Text != "To")
                {
                    //Recursion stuff...
                    string sourceDirectory = fromBrowse.SelectedPath;
                    string destinationDirectory = toBrowse.SelectedPath;
                    //Sends origination path to function ae this is a function call. its num = 8675309... I think its name is Jenny.
                    recursiveRecursion(sourceDirectory, destinationDirectory, fileExtension, intCounter);
                }
                else
                {
                    //Message box that says it is required to
                    MessageBox.Show("You dun goofed");
                }
            }
            else
            {
                //Yup, it's a message box.
                //That was an unhelpful comment....
                /Aalmost as unhelpful as this comment
                // This is what happens when I program stoned.
                MessageBox.Show("You dun goofed");
            }

            //Grabs the path of the originating directory.
            //After the originating directory path is choosen, send the path to a recursion function
            //which will search the folders and sort the files in the dir. path.
        }


        private void originationLabel_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Silly user, I am a label. I dont even click");
        }


        private void sendingLabel_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Silly user, I am a label. I dont even click");
        }
        //Recursion function which grabs the directory path, uses a foreach loop to iterate through the files.
        //Whilst each file is iterated through, have the recursive function select the files by extension and copy
        //the files to another directory chosen by the user.
        private void recursiveRecursion(string sourceDirectory, string destinationDirectory, string fileExtension, int intCounter)
        {
            //Select files Path and stuff
            string[] filenames = Directory.GetFiles(sourceDirectory, fileExtension);
            //foreach (string directoryName in directoryNames)
            string[] directoryNames = Directory.GetDirectories(sourceDirectory);
            //dir is the file name, as in for each file name in directory do the thing in this recursion loop thingy.
            foreach (string fileName in filenames)
            {
                try
                {
                    if (File.Exists(fileName))
                    {
                        //Don't use recursion. It is a file
                        //copy files here and stuff.

                        intCounter  ;
                        //For the destination file ae dir2 to work, I need to get the file name from the file path.
                        //Currently dir is the file path.
                        //Enter code here to get the file name from the file path.

                        //Displays on label name of the file.
                        this.filesortTextbox.Text = "the file being copied is "   fileName;
                        //Gets filename from path

                        string fileNameOfficial = Path.GetFileName(fileName);
                        //Enters text of filename into filename textbox
                        filenameTextbox.Text = fileNameOfficial;

                        //For copying purposes, adds filename to originating directory path.
                        string inputFile = sourceDirectory   "\"   fileNameOfficial;

                        //Assigns image from the origination directory.
                        Image img = Image.FromFile(inputFile);
                        // Shows image in the image viewer...
                        iteratedPicturebox.Image = img;
                        iteratedPicturebox.Width = img.Width;
                        iteratedPicturebox.Height = img.Height;

                        //Allows the user to change file name, after changing filename allows
                        //user to go to next file to rename. This is awesome for files...

                        paused = true;
                        bool X = false;
                        label2.Text = "Please choose a file name and press next.";
                        //while statement
                        while (X == false)
                        {
                            if (paused == false)
                            {
                                //Renames filename
                                string newFileName = filenameTextbox.Text;

                                //Adds filename to selected directory where user wishes to send file to.
                                string outputFile = destinationDirectory   "\"   intCounter   fileNameOfficial;

                                //Pause statement to move to next operand..

                                //Copies post iterated file to selected directory.
                                File.Copy(inputFile, outputFile, true);
                                X = true;
                            }
                        }
                    }
                    else
                    {
                        //This really has an unknown pourpose, admittably keeping here for good luck...
                        Console.WriteLine("{0} is not a valid file or directory.", fileName);
                    }
                }

                catch (Exception e)
                {
                    //What process failed you ask? Good question mate.
                    Console.WriteLine("The process failed: {0}", e.ToString());
                }
            }

            //Long story short for each directory contained in the list of directories.
            //Do the stuff listed in the foreach statement.
            foreach (string directoryName in directoryNames)
            {
                try
                {
                    if (Directory.Exists(directoryName))
                    {
                       //If this is a directory, send the thing through itself.
                       // MessageBox.Show("now going through the "  directoryName   " directory");
                       recursiveRecursion(directoryName, destinationDirectory, fileExtension, intCounter);
                       this.directoryIterated.Text = "The Current Directory The Files Are being copied from is "   directoryName;
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine("The process failed: {0}", e.ToString());
                }
            }
        }

        private void fileExtensionTextbox_TextChanged(object sender, EventArgs e)
        {

        }

        private void label1_Click(object sender, EventArgs e)
        {
        }

        private void directoryIterated_Click(object sender, EventArgs e)
        {
            MessageBox.Show("I am a label. I don't even click");
            this.directoryIterated.Text = "You pressed me.";
        }

        private void kill_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void filesortTextbox_Click(object sender, EventArgs e)
        {
            MessageBox.Show("I am a label. I don't even click.");
            this.directoryIterated.Text = "You pressed me.";

        }

        private void iteratedPicturebox_Click(object sender, EventArgs e)
        {
            MessageBox.Show("I am a picture box, I don't even click.");
        }

        private void nextButton_Click(object sender, EventArgs e)
        {
            if (paused == false)
            {
                paused = true;
            }
            else
            {
                paused = false;
            }
        }
    }
}
  

Комментарии:

1. Похоже, вы используете цикл while, который выполняется бесконечно, чтобы «приостановить» программу. Я не уверен, насколько хорошо это будет работать, но попробуйте добавить Application.DoEvents(); внутри этого цикла while и расскажите мне, как это происходит

2. Ну, да, ваша программа зависнет, если она выполняет этот цикл. Пока поток пользовательского интерфейса выполняет цикл, он не может очень хорошо реагировать на нажатие кнопки. В чем именно причина цикла? Кроме того, вместо вашего recursiveRecursion , взгляните на Directory.EnumerateFiles , msdn.microsoft.com/en-us/library/dd383458.aspx , и Directory.EnumerateDirectories , что несколько упростит вашу жизнь.

3. Я бы вообще избегал цикла обработки. Или оставьте это, но заставьте его вызывать модальное диалоговое окно для каждого ввода.

4. @mazzzzz: Использование Application.DoEvents() никогда не бывает правильным. Оставьте поток пользовательского интерфейса для выполнения работы с пользовательским интерфейсом. Пусть вычисления и другие вещи выполняются в отдельных потоках, тогда вам не придется прибегать к использованию этого ужасного метода в первую очередь.

5. Поверьте мне, я знаю, но я не собираюсь объяснять правильный способ сделать это в комментарии, и у меня нет времени, чтобы написать полное объяснение того, почему это ужасная идея, поэтому я просто сначала убедился, что это проблема. Запуск его в асинхронном режиме был бы вариантом, но лучшим способом было бы изменить порядок приложения, чтобы оно работало вне событий. Следовало бы добавить это в мой последний комментарий, хотя ^^

Ответ №1:

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

Комментарии:

1. На самом деле это не ответ на вопрос, поскольку речь шла о взаимодействии с пользователем, а не о выполнении работы в фоновом режиме.

Ответ №2:

Вместо того, чтобы пытаться остановить выполнение, я бы отобразил диалоговое окно:

  1. Создайте форму, например: FileRenameDialog .
  2. Добавьте общедоступные свойства в форму, которую вы можете использовать для задания: текст и т. Д.
  3. Создайте экземпляр формы. например: FileRenameDialog reuseme
  4. Всякий раз, когда пользователю нужно сделать выбор, введите текст в диалоговом окне. например: reuseme.Source = "The current file being copied...";
  5. Отобразить диалоговое окно для пользователя как модальное, например: var dlgResult = reuseme.ShowDialog(this);
  6. Делайте то, что вам нужно, с результатом, например: if (dlgResult == DialogResult.OK) {...do stuff with the properties of reuseme...}