• Добро пожаловать на сайт - Forumteam.digital !

    Что бы просматривать темы форума необходимо зарегестрироваться или войти в свой аккаунт.

    Группа в телеграме (подпишитесь, что бы не потерять нас) - ForumTeam Chat [Подписатся]
    Связь с администратором - @ftmadmin

41. Элементы управления на практике и задание на дом.

Redman

<FORUMTEAM>
Команда форума
Регистрация
13.11.17
Сообщения
13.340
Реакции
8.377
Баллы
1.200
FTC
208¢
Данная программа позволяет осуществлять поиск файлов по маске (в формате MS-DOS) в указанном пользователем каталоге, включая подкаталоги. После отображения списка найденных файлов, пользователь сможет осуществить следующие действия (файлы, над которыми производятся операции, должны быть предварительно выделены):

  • удалить выделенные файлы
  • скопировать выделенные файлы в каталог, указанный пользователем
  • перейти в каталог(-и), где находятся выделенные файлы
Код:
using System;
using System.Drawing;
using System.Windows.Forms;

// Работа с ресурсами
using System.Resources;

// Файлы
using System.IO;

// Регулярные выражения
using System.Text.RegularExpressions;

// Используется для работы с процессами, точнее для работы
// с функциями класса Process
// public static Process Start(string fileName); -
// позволяет запустить указанный процесс или процесс, ассоциированный с указанным файлом;
// public static Process Start(string fileName, string arguments); - тоже самое,
// во втором параметре передаются аргументы командной строки.
using System.Diagnostics;

// Работа с файлами, которые ищутся по вводимой маске
namespace CSharpApplication.SearchFileByMask
{
    class Search : Form
    {
        // Строка для ввода пути
        private TextBox Path;
        // Строка для ввода маски
        private TextBox Mask;
        // Кнопка для вызова стандартного диалога выбора каталогов
        private Button Browse;
        // Кнопка поиска
        private Button GoSearch;
        // Флаг для поиска в подкаталогах указанного каталога
        private CheckBox SubDir;
        // Список найденных файлов
        private ListBox FilesList;
        // Приглашение для ввода маски
        private Label MaskText;
        // Приглашение для ввода пути
        private Label PathText;     
        // Стандартный диалог выбора каталогов
        private FolderBrowserDialog BrowserDialog;
        // Меню верхнего уровня
        private MainMenu TopMenu;
        // Пункт "Выход"
        private MenuItem menuItemExit;
        // Выпадающее меню "Операции"
        private MenuItem menuItemOperations;
        // Пункт "Удалить выделенные файлы"
        private MenuItem menuItemDelete;
        // Пункт "Переместить выделенные файлы в ..."
        private MenuItem menuItemMove;
        // Пункт "Перейти к выделенным файлам"
        private MenuItem menuItemGo;
       
        static void Main()
        {
            // Запуск приложения
            Application.Run(new Search());
        }

        /****************************************************************/
        /* Данная функция ранее называлась InitializeComponent.
         * Эту функцию создает редактор ресурсов, и, в принципе,
         * для начала она кажется довольно удобной. Но после
         * некоторого времени работы с редактором ресурсов автора данной
         * программы стало безумно раздражать его помощь.
         * Дело в том, что, как и большинство программ компании Microsoft,
         * данный редактор стремится оказать максимально возможную помощь,
         * после чего код функции дико разрастается из-за подробнейшего
         * описания каждой мелочи (вспомните написания HTML-файлов в
         * Microsoft Word). Поэтому после составления формы, автор
         * переименовал функцию и подчистил написанный редактором код.
         ***************************************************************/
        private void InitializeComponents()
        {
            // Класс для работы с менеджером ресурсов
            ResourceManager resources = new ResourceManager(typeof(Search));
           
            /*********************************************************/
            /* Создание элементов управления
            /*********************************************************/

            this.PathText = new Label();
            this.MaskText = new Label();
           
            this.Path = new TextBox();
            this.Mask = new TextBox();
           
            this.FilesList = new ListBox();
           
            this.Browse = new Button();
            this.GoSearch = new Button();
           
            this.SubDir = new CheckBox();

            this.BrowserDialog = new FolderBrowserDialog();
           
            this.TopMenu = new MainMenu();

            this.menuItemOperations = new MenuItem();

            this.menuItemExit = new MenuItem();
            this.menuItemDelete = new MenuItem();
            this.menuItemMove = new MenuItem();
            this.menuItemGo = new MenuItem();
           
            /* Замораживаем ресурсы.
             * Это нужно для того, чтобы во время создания и
             * расположения на форме элементов управления
             * они не обрабатывали сообщений о собственных
             * изменениях размеров, координат и т. д.
            */

            this.SuspendLayout();
           
            // В основном добавлено редактором ресурсов!!!
           
            //
            // PathText
            //
            // Авторазмер
            this.PathText.AutoSize = true;
            // Цвет текста
            this.PathText.ForeColor = Color.Blue;
            // Позиция
            this.PathText.Location = new Point(0, 5);
            // Имя
            this.PathText.Name = "PathText";
            // Переход по табуляции (для надписей не имеет смысла)
            this.PathText.TabIndex = 0;
            // Текст
            this.PathText.Text = "Выберите каталог для поиска:";
            //
            // MaskText
            //
            this.MaskText.AutoSize = true;
            this.MaskText.ForeColor = Color.Blue;
            this.MaskText.Location = new Point(0, 40);
            this.MaskText.Name = "MaskText";
            this.MaskText.TabIndex = 1;
            this.MaskText.Text = "Введите маску для файлов:";
            //
            // Path
            //

            // Привязка элемента к определенным сторонам формы -
            // используется для сохранений пропорций элемента
            // при изменении размеров формы

            this.Path.Anchor = AnchorStyles.Top | AnchorStyles.Left
                | AnchorStyles.Right;
            this.Path.AutoSize = false;
            this.Path.Location = new Point(0, 20);
            this.Path.Name = "Path";
            this.Path.Size = new Size(269, 20);
            this.Path.TabIndex = 2;
            this.Path.Text = "";
            // Обработчик события изменения текста
            this.Path.TextChanged += new EventHandler(this.OnPathChanged);
            //
            // Mask
            //
            this.Mask.Anchor = AnchorStyles.Top | AnchorStyles.Left
                | AnchorStyles.Right;
            this.Mask.Location = new Point(0, 55);
            this.Mask.Name = "Mask";
            this.Mask.Size = new Size(140, 20);
            this.Mask.TabIndex = 4;
            this.Mask.Text = "";
            // Обработчик события нажатия клавиши
            this.Mask.KeyDown += new KeyEventHandler(this.OnMaskKeyDown);
            //
            // FilesList
            //
            this.FilesList.Anchor = AnchorStyles.Top | AnchorStyles.Bottom
                | AnchorStyles.Left | AnchorStyles.Right;
            this.FilesList.Location = new Point(0, 85);
            this.FilesList.Name = "FilesList";
            // Режим мультивыборки (с зажатыми Control'ом или Shift'ом)
            this.FilesList.SelectionMode = SelectionMode.MultiExtended;
            this.FilesList.Size = new Size(301, 186);
            this.FilesList.TabIndex = 7;
            //
            // Browse
            //
            this.Browse.Anchor = AnchorStyles.Top | AnchorStyles.Right;
            this.Browse.ForeColor = Color.Blue;
            this.Browse.Location = new Point(277, 20);
            this.Browse.Name = "Browse";
            this.Browse.Size = new Size(24, 23);
            this.Browse.TabIndex = 3;
            this.Browse.Text = "...";
            // Обработчик нажатия кнопки
            this.Browse.Click += new EventHandler(this.OnBrowseClick);
            //
            // GoSearch
            //
            this.GoSearch.Anchor = AnchorStyles.Top | AnchorStyles.Right;
            this.GoSearch.Enabled = false;
            this.GoSearch.ForeColor = Color.Blue;
            this.GoSearch.Location = new Point(235, 55);
            this.GoSearch.Name = "GoSearch";
            this.GoSearch.Size = new Size(65, 23);
            this.GoSearch.TabIndex = 6;
            this.GoSearch.Text = "Поиск";
            // Обработчик нажатия кнопки
            this.GoSearch.Click += new EventHandler(this.OnSearchClick);
            //
            // SubDir
            //
            this.SubDir.Anchor = AnchorStyles.Top | AnchorStyles.Right;
            this.SubDir.ForeColor = Color.Blue;
            this.SubDir.Location = new Point(143, 50);
            this.SubDir.Name = "SubDir";
            this.SubDir.Size = new Size(95, 28);
            this.SubDir.TabIndex = 5;
            this.SubDir.Text = "Поиск в\nподкаталогах";
            //
            // BrowserDialog
            //
            // Надпись на диалоге в момент появления
            this.BrowserDialog.Description = "Выбор каталога для поиска";
            // Кнопка "Создать новую папку" выключена
            this.BrowserDialog.ShowNewFolderButton = false;
            //
            // TopMenu
            //
            // Создание меню верхнего уровня
            this.TopMenu.MenuItems.AddRange(new MenuItem[]
                                            {
                                                this.menuItemExit,
                                                this.menuItemOperations
                                            }
                                           );
            //
            // menuItemExit
            //
            // Порядковый номер пункта меню в данном подменю
            this.menuItemExit.Index = 0;
            // Горячая комбинация клавиш
            this.menuItemExit.Shortcut = Shortcut.CtrlX;
            // Текст
            this.menuItemExit.Text = "&Выход";
            // Обработчик выбора пункта меню
            this.menuItemExit.Click += new EventHandler(this.OnMenuExitClick);
            //
            // menuItemOperations
            //
            this.menuItemOperations.Index = 1;
            this.menuItemOperations.MenuItems.AddRange(new MenuItem[]
                                                       {
                                                           this.menuItemDelete,
                                                           this.menuItemMove,
                                                           this.menuItemGo
                                                       }
                                                      );           
            this.menuItemOperations.Text = "&Операции";
            // Обработчик, срабатывающий перед отображением выпадаюшего меню
            this.menuItemOperations.Popup += new EventHandler(this.OnMenuPopup);
            //
            // menuItemDelete
            //
            this.menuItemDelete.Index = 0;
            this.menuItemDelete.Text = "Удалить выделенные файлы";
            this.menuItemDelete.Click += new EventHandler(menuItemDelete_Click);
            //
            // menuItemMove
            //
            this.menuItemMove.Index = 1;
            this.menuItemMove.Text = "Переместить выделенные файлы в ...";
            this.menuItemMove.Click += new EventHandler(menuItemMove_Click);
            //
            // menuItemGo
            //
            this.menuItemGo.Index = 2;
            this.menuItemGo.Text = "Перейти к выделенным файлам";
            this.menuItemGo.Click += new EventHandler(menuItemGo_Click);
           
            // Создание контекстного меню на основе существующего подменю.
            // Обратите внимание на то, что пункты меню, которые уже находятся
            // в каком-либо подменю, нельзя добавлять куда-либо повторно.
// Поэтому указанные ниже пункты перед добавлением клонируются.

            this.FilesList.ContextMenu =
                new ContextMenu(new MenuItem[]
                                {
                                    this.menuItemDelete.CloneMenu(),
                                    this.menuItemMove.CloneMenu(),
                                    this.menuItemGo.CloneMenu()
                                }
                               );
            // Обработчик вызова контекстного меню для списка.
            // Срабатывает при щелчке правой кнопкой мыши по элементу.
            this.FilesList.ContextMenu.Popup += new EventHandler(this.OnMenuPopup);
            // Обработчик двойного щелчка по списку
            this.FilesList.DoubleClick += new EventHandler(FilesList_DoubleClick);
           
            //
            // Search
            //
            this.AutoScaleBaseSize = new Size(5, 13);
            this.BackColor = SystemColors.Control;
            this.ClientSize = new Size(302, 273);

            // Добавляем элементы управления в коллекцию элементов формы
            // (форма становится их родителем)
            this.Controls.AddRange(new Control[]
                                  {
                                      this.GoSearch,
                                      this.MaskText,
                                      this.Browse,
                                      this.FilesList,
                                      this.Mask,
                                      this.SubDir,
                                      this.Path,
                                      this.PathText}
                                  );

            // Вынимаем иконку из ресурсов и прибиваем к форме
            this.Icon = ((Icon)(resources.GetObject("$this.Icon")));
            // Натягиваем меню
            this.Menu = this.TopMenu;
            // Устанавливаем минимально возможный размер для формы
            this.MinimumSize = new Size(300, 300);
            this.Name = "Search";
            // Позиция формы при первом отображении
            this.StartPosition = FormStartPosition.CenterScreen;
            this.Text = "Поиск файлов";

            // Размораживаем элементы управления
            this.ResumeLayout(false);

        }

        Search()
        {
            // Инициализируем форму и элементы управления на ней
            InitializeComponents();
        }

        // Функция для инициализации поиска фалов по маске
        private void StartSearch()
        {
            // Проверка корректности указанного пути
            if(!Directory.Exists(Path.Text))
            {
                // Все плохо
                MessageBox.Show("Каталог " + Path.Text + " открыть не удалось",
                    "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            // Дописываем слэш (если есть необходимость)
            if(Path.Text[Path.Text.Length - 1] != '\\')
                Path.Text += '\\';

            // Если маска не указана
            if(Mask.Text.Length == 0)
            {
                // Маска по умолчанию
                Mask.Text = "*.*";
            }

            // Убираем лишние пробелы позади указанного пути
            Path.Text = Path.Text.TrimEnd();
           
            // Преобразуем введенную маску для файлов
            // в регулярное выражение

            // Заменяем . на \.
            string RegMask = Mask.Text.Replace(".", @"\.");
            // Заменяем ? на .
            RegMask = RegMask.Replace("?", ".");
            // Заменяем * на .*
            RegMask = RegMask.Replace("*", ".*");
            // Указываем, что требуется найти точное соответствие маске
            RegMask = "^" + RegMask + "$";

            // Создание объекта регулярного выражения
            // на основе маски
            Regex RegExpr = new Regex(RegMask, RegexOptions.IgnoreCase);

            string PathToDirectory = Path.Text;

            // Очистка содержимого списка
            FilesList.Items.Clear();

            // Запускаем функцию поиска
            uint Count = FillListOfFiles(PathToDirectory, RegExpr);

            MessageBox.Show("Количество файлов в каталоге \n" + Path.Text +
                " , \nкоторые соответствуют маске, равно " + Count,
                "Операция завершена", MessageBoxButtons.OK,
                MessageBoxIcon.Information);
        }

        // Функция, осуществляющая поиск файлов по указанной маске
        private uint FillListOfFiles(string dir, Regex mask)
        {
            // Количество найденных элементов
            uint Count = 0;

            string [] names;
            try
            {
                // Пытаемся получить список каталогов
                // (а прав может и не быть :-( )
                names = Directory.GetFiles(dir);
            }
            catch
            {
                // Закругляемся
                return Count;
            }

            // Перебираем найденные элементы
            foreach(string name in names)
            {
                // А подошла ли маска ?!!
                if(mask.IsMatch(name))
                {
                    // Добавляем файл в список
                    FilesList.Items.Add(name);
                    ++Count;
                }
            }

            // Если хочется войти глубже (просмотр подкаталогов)
            if(this.SubDir.Checked)
            {
                // Получаем список имеющихся в наличии подкаталогов
                string [] dirnames = Directory.GetDirectories(dir);
                // Берем по одному
                foreach(string dirname in dirnames)
                {
                    // Запускаем функцию от него
                    Count += FillListOfFiles(dirname, mask);
                }
            }

            // Возвращаем количество найденных файлов
            return Count;
        }
        // Обрабатываем изменение текста в текстовом поле
        private void OnPathChanged(object sender, EventArgs e)
        {
            // Удаляем ведущие пробелы
            Path.Text = Path.Text.TrimStart();
            // Нет текста?
            if(Path.Text.Length == 0)
            {
                // Нет поиска!
                GoSearch.Enabled = false;
            }
            else
            {
                // Кнопка гори!!!
                GoSearch.Enabled = true;
            }
        }

        // Обрабатываем вызов диалога выбора каталогов
        private void OnBrowseClick(object sender, EventArgs e)
        {
            // Если введенный текст таки каталог
            if(Directory.Exists(Path.Text))
            {
                // Добавляем слэш (при необходимости)
                if(Path.Text[Path.Text.Length - 1] != '\\')
                    Path.Text += '\\';
                // Выбираем введенный путь в качестве стартового для диалога
                BrowserDialog.SelectedPath = Path.Text;
            }

            // Кнопка "Создать новую папку" для диалога отключена
            BrowserDialog.ShowNewFolderButton = false;
            // Отбражаем диалог и ждем чего будет
            if(BrowserDialog.ShowDialog() == DialogResult.OK)
            {
                // Если user определился, то его выбор - наш выбор
                Path.Text = BrowserDialog.SelectedPath;
            }       
        }

        // Нажали кнопку "Поиск"
        private void OnSearchClick(object sender, EventArgs e)
        {
            StartSearch();
        }
        // Обрабатываем нажатия кнопок в поле для ввода маски
        private void OnMaskKeyDown(object sender, KeyEventArgs e)
        {
            // Если нажали Enter и кнопка "Поиск" доступна
            if(e.KeyCode == Keys.Enter && GoSearch.Enabled == true)
            {
                // Запускаем поиск
                StartSearch();
            }
        }
        // Пункт меню "Выход"
        private void OnMenuExitClick(object sender, EventArgs e)
        {
            // Закрываемся
            Close();
        }
        // Меню желает отобразиться
        private void OnMenuPopup(object sender, EventArgs e)
        {

            // Приводимся к базовому классу
            Menu menu = (Menu)sender;

            // Если в списке нет веделенных файлов
            if(FilesList.SelectedItems.Count == 0)
            {           
                // Вырубаем пункты подменю
                foreach(MenuItem mi in menu.MenuItems)
                {
                    mi.Enabled = false;
                }
            }
            else
            {
                // Оживляем пункты подменю
                foreach(MenuItem mi in menu.MenuItems)
                {
                    mi.Enabled = true;
                }
            }
        }
        // Желаем удалять выделенные файлы
        private void menuItemDelete_Click(object sender, EventArgs e)
        {
            // Переспрашиваем
            DialogResult Yes = MessageBox.Show("Вы уверены?", "Удаление файлов",
                MessageBoxButtons.YesNo, MessageBoxIcon.Question);

            // Пользователь на все согласен
            if(Yes == DialogResult.Yes)
            {
                // Считаем "смертничков"
                int Count = FilesList.SelectedIndices.Count;
                for(int i = Count - 1; i >= 0; i--)
                {
                    // Удаляем файлы
                    File.Delete((string)FilesList.SelectedItems[i]);
                    // Удаляем запись из списка
                    FilesList.Items.RemoveAt(FilesList.SelectedIndices[i]);
                }
            }
        }
        // Желаем переместить файлы в сухое, прохладное место
        private void menuItemMove_Click(object sender, EventArgs e)
        {
            // Даем шанс создать папку на ходу (в диалоге выбора каталогов)
            BrowserDialog.ShowNewFolderButton = true;
            string dir;
            // Отображаем каталог
            if(BrowserDialog.ShowDialog() == DialogResult.OK)
            {
                // Записываем выбранный путь
                dir = BrowserDialog.SelectedPath;
            }
            else
                // Не хочет - не надо
                return;
           
            // Считаем "эмигрантов"
            int Count = FilesList.SelectedIndices.Count;
            string name, path;
            for(int i = Count - 1; i >= 0; i--)
            {
                // Получаем путь к файлу из списка
                path = (string)FilesList.SelectedItems[i];
                // Выкусываем имя файла
                name = path.Substring(path.LastIndexOf('\\'));
                // Перемещаем файл на новое место жительство
                File.Move(path, dir + name);
                // Удаляем следы пребывания файла в списке
                FilesList.Items.RemoveAt(FilesList.SelectedIndices[i]);
            }
        }

        // Желаем видеть место жительства файла и его соседей
        private void menuItemGo_Click(object sender, EventArgs e)
        {
            // Считаем места, в которые надо заглянуть
            int Count = FilesList.SelectedIndices.Count;
            string oldpath = "", newpath;
            for(int i = 0; i < Count; i++)
            {
                // Забираем путь из списка
                newpath = (string)FilesList.SelectedItems[i];
                // Откусываем имя файла
                newpath = newpath.Substring(0, newpath.LastIndexOf('\\'));
                // Если этот путь в списке посещений уже присутствует
                if(newpath == oldpath)
                    continue;
                // Осматриваем место жительства очередного файла
                Process.Start("explorer.exe", newpath);
                // Запоминаем где были в последний раз
                oldpath = newpath;
            }
        }

        // Есть желание запустить файл
        private void FilesList_DoubleClick(object sender, EventArgs e)
        {
            // Считаем количество "желающих"
            if(FilesList.SelectedIndices.Count == 0)
                return;
            // Запуск
            Process.Start((string)FilesList.SelectedItem);
        }
    }
}

Домашнее задание
Реализовать приложение-справочник по автомобилям. Должны поддерживаться функции добавления, удаления, модификации, поиска, сохранения в файл и загрузки из файла информации.
 
Сверху Снизу