Создайте список недавно использованных файлов (MRU) в C#

В списке MRU отображаются файлы, которые программа использовала совсем недавно в меню. Если пользователь выбирает файл из списка, программа снова открывает этот файл.

В этом примере создается класс MruList, который программа может использовать для упрощения предоставления списка MRU. Этот пример довольно сложен, кроме того многие его части интересны, поэтому я собираюсь описать их все, разделяя на следующие сегменты.

Инициализация

// Имя приложения
private string ApplicationName;
// Список файлов
private int NumFiles;
private List FileInfos;
// Меню файлов
private ToolStripMenuItem MyMenu;
// Пункты меню, используемые для отображения файлов
private ToolStripSeparator Separator;
private ToolStripMenuItem[] MenuItems;
// Всплывает, когда пользователь выбирает файл из списка MRU.
public delegate void FileSelectedEventHandler(FileInfo file_info);
public event FileSelectedEventHandler FileSelected;

Переменная ApplicationName содержит имя приложения. Это используется для хранения информации о файлах в реестре.

В переменной NumFiles содержится количество файлов, которые может храниться в списке, а не количество файлов, которые оно фактически удерживает в то время. Большинство программ устанавливают это значение равным 4, поэтому список MRU может содержать не более 4 файлов.

Список FileInfos содержит объекты FileInfo, описывающие файлы, находящиеся в списке. (Я использую объекты FileInfo, потому что они легко сохраняют полный путь файла и краткое имя файла. Вместо этого вы можете использовать какой-то другой тип объекта, если хотите, чтобы список MRU представлял что-то другое, кроме файлов. Например, если вы хотите получить список недавно используемых инженерных диаграмм, вы можете захотеть, чтобы в этом списке содержались объекты, в которых хранятся заголовки диаграмм, расположение файлов и другие данные.

Переменная MyMenu содержит ссылку на меню программы, которая должна отображать список. Переменные Separator и MenuItems содержат ссылки на элементы меню, созданные MruList.

Делегат FileSelectedEventHandler определяет тип события FileSelected, которое MruList повышает, когда пользователь выбирает файл из списка.

В следующем коде показан конструктор класса, который инициализирует список.

// Конструктор.
public MruList(string application_name, ToolStripMenuItem menu,
    int num_files)
{
ApplicationName = application_name;
MyMenu = menu;
NumFiles = num_files;
FileInfos = new List();
// Создаем разделитель.
Separator = new ToolStripSeparator();
Separator.Visible = false;
MyMenu.DropDownItems.Add(Separator);
// Создаем пункты меню которые могут понадобиться позже.
MenuItems = new ToolStripMenuItem[NumFiles + 1];
for (int i = 0; i < NumFiles; i++)
{
MenuItems[i] = new ToolStripMenuItem();
MenuItems[i].Visible = false;
MyMenu.DropDownItems.Add(MenuItems[i]);
}
// Заново загружаем пункты из реестра.
LoadFiles();
// Отображаем пункты.
ShowFiles();
}

Конструктор сохраняет имя приложения, меню, которое должно содержать элементы списка, и количество файлов, которые может содержать список. Затем он создает новый список FileInfos.

Затем конструктор создает разделитель и пункты меню, которые могут потребоваться для отображения позже. Он заканчивается вызовом LoadFiles для загрузки сохраненных файлов из реестра и ShowFiles для отображения правильных пунктов меню.

Следующий код показывает метод LoadFiles.

// Загружаем сохраненные пункты из реестра.
private void LoadFiles()
{
// Последовательно загружает пункты из реестра.
for (int i = 0; i < NumFiles; i++)
{
string file_name = (string)RegistryTools.GetSetting(
ApplicationName, "FilePath" + i.ToString(), "");
if (file_name != "")
{
FileInfos.Add(new FileInfo(file_name));
}
}
}

Метод LoadFiles использует метод GetSetting класса RegistryTools для загрузки имен файлов, хранящихся в реестре. Следующий код показывает метод GetSetting.

// Получаем значения.
public static object GetSetting(string app_name, string name, object default_value)
{
RegistryKey reg_key = Registry.CurrentUser.OpenSubKey("Software", true);
RegistryKey sub_key = reg_key.CreateSubKey(app_name);
return sub_key.GetValue(name, default_value);
}

Метод GetSetting открывает раздел реестра текущего пользователя, получает подраздел, названный в честь приложения, а затем получает запрошенный параметр, который в этом случае является файловым путем.

После того, как конструктор загрузил сохраненную информацию о файле из реестра, он вызывает следующий метод ShowFiles для подготовки элементов меню для использования.

// Отображение файлов в пунктах меню
private void ShowFiles()
{
Separator.Visible = (FileInfos.Count > 0);
for (int i = 0; i < FileInfos.Count; i++)
{
MenuItems[i].Text = string.Format("&{0} {1}", i + 1, FileInfos[i].Name);
MenuItems[i].Visible = true;
MenuItems[i].Tag = FileInfos[i];
MenuItems[i].Click -= File_Click;
MenuItems[i].Click += File_Click;
}
for (int i = FileInfos.Count; i < NumFiles; i++)
{
MenuItems[i].Visible = false;
MenuItems[i].Click -= File_Click;
}
// Update the Registry.
SaveFiles();
}

Метод ShowFiles начинается с отображения разделителя, если в списке есть какие-либо файлы. Затем он перебирает объекты FileInfo в коллекции FileInfos. Для каждого объекта он устанавливает соответствующее пункту меню свойство текста, видимости и тега. Он также прикрепляет обработчик события File_Click к событию Click элемента меню. (Сначала он удаляет любой ранее установленный обработчик событий, поэтому обработчик события не устанавливается дважды).

Затем код скрывает любые пункты меню, которые не нужны.

Следующий код показывает метод SaveFiles, который сохраняет текущий список файлов в реестре.

// Сохраняет текущий элемент в реестр.
private void SaveFiles()
{
// Удаление сохраненных записей.
for (int i = 0; i < NumFiles; i++)
{
RegistryTools.DeleteSetting(ApplicationName, "FilePath" + i.ToString());
}
// Сохранение текущих записей.
int index = 0;
foreach (FileInfo file_info in FileInfos)
{
RegistryTools.SaveSetting(ApplicationName,
"FilePath" + index.ToString(), file_info.FullName);
index++;
}
}

Метод SaveFiles удаляет все существующие записи реестра, а затем сохраняет полные пути текущих файлов.

Добавление и удаление файлов

Когда основная программа открывает файл или сохраняет вновь созданный файл, он должен вызывать метод AddFile MruLists, показанный в следующем коде.

// Добавление файлов в список, переставляя при необходимости.
public void AddFile(string file_name)
{
// Удаление файла из списка.
RemoveFileInfo(file_name);
// Add the file to the beginning of the list.
FileInfos.Insert(0, new FileInfo(file_name));
// Если слишком много элементов, удаляем последний.
if (FileInfos.Count > NumFiles) FileInfos.RemoveAt(NumFiles);
// Отображение файлов.
ShowFiles();
// Обновить реестр.
SaveFiles();
}

Этот метод вызывает метод RemoveFileInfo для удаления файла из списка FileInfos, а затем вставляет файл в начало списка. Это не позволяет списку содержать дубликаты. Затем, если в списке содержится слишком много файлов, код удаляет последний элемент. Метод заканчивается вызовом ShowFiles для обновления пунктов меню и SaveFiles для сохранения текущего списка в реестре.

Следующий код показывает метод RemoveFileInfo.

// Удаление информации о файле из списка.
private void RemoveFileInfo(string file_name)
{
// Удаление вхождения информации о файле из списка.
for (int i = FileInfos.Count - 1; i >= 0; i--)
{
if (FileInfos[i].FullName == file_name) FileInfos.RemoveAt(i);
}
}

Этот метод циклически перемещается по элементам файла с конца. Если он находит запись с именем целевого файла, она удаляет эту запись. (Код выполняет поиск по списку задом наперед, поэтому удаление элемента не перенумерует остальные элементы.) Обратите внимание, что код не может просто использовать метод удаления списка, потому что этот метод ищет только сопоставленные объекты FileInfo, а не объекты, которые отличаются, а представляют один и тот же файл.

Метод RemoveFile, показанный в следующем коде, удаляет файл из списка MRU. Основная программа должна вызывать этот метод всякий раз, когда ему нужно удалить файл из списка. Например, если программа пытается открыть файл и не может, большинство программ удаляют этот файл из списка MRU.

// Удаление файла из списка, переставляя при необходимости.
public void RemoveFile(string file_name)
{
// Удаление файла из списка.
RemoveFileInfo(file_name);
// Отображение файлов.
ShowFiles();
// Обновление реестра.
SaveFiles();
}

Этот метод вызывает RemoveFileInfo для удаления файла из списка. Затем он вызывает ShowFiles для обновления пунктов меню и SaveFiles для обновления реестра.

Управление событиями.

Когда пользователь выбирает файл из списка MRU, выполняется следующий обработчик события File_Click.

// Пользователь выбрал файл из меню.
private void File_Click(object sender, EventArgs e)
{
// Ничего не делать, если никто не хочет поймать событие.
if (FileSelected != null)
{
// Получить соответствующий объект FileInfo.
ToolStripMenuItem menu_item = sender as ToolStripMenuItem;
FileInfo file_info = menu_item.Tag as FileInfo;
// Выделить событие.
FileSelected(file_info.FullName);
}
}

Этот метод просто вызывает событие FileSelected, передавая ему объект FileInfo, представляющий выбранный файл.

Использование Mru-списка

В данном примере используется следующий код для определения и инициализации переменной MruList.

// Mru-список.
MruList MyMruList;
// Создаем Mru-список.
private void Form1_Load(object sender, EventArgs e)
{
MyMruList = new MruList("howto_mru_list", mnuFile, 4);
MyMruList.FileSelected += MyMruList_FileSelected;
}

Программа определяет переменную MyMruList на уровне формы, поэтому все ее методы могут ее использовать. Обработчик события Load формы инициализирует MruList и регистрирует обработчик события MyMruList_FileSelected для обработки события FileSelected в списке.

Следующий код показывает, как программа пытается открыть файл.

// Открытие файла и добавление его в список MRU.
private void OpenFile(string file_name)
{
try
{
// Загрузка файла.
rchFile.Clear();
if (file_name.ToLower().EndsWith(".rtf"))
{
rchFile.LoadFile(file_name);
}
else
{
rchFile.Text = File.ReadAllText(file_name);
}
// Добавление файла в список MRU.
MyMruList.AddFile(file_name);
}
catch (Exception ex)
{
// Удаление файла из списка MRU.
MyMruList.RemoveFile(file_name);
// Сообщение пользователю о произошедшем.
MessageBox.Show(ex.Message);
}
}

Если файл имеет имя, которое заканчивается на .rtf, программа использует метод LoadFile для управления RichTextBox для загрузки файла в виде файла RTF. Если имя не заканчивается на .rtf, программа загружает файл в виде текста. Если он успешно загружает файл, программа вызывает метод AddLile для MRULIST, чтобы добавить файл в список MRU.

Если программе не удается загрузить файл, она вызывает метод RemoveFile для MRULIST, чтобы удалить файл из списка MRU, и сообщает пользователю, что возникла проблема.

Если пользователь выбирает файл из списка MRU, MruList вызывает событие FileSelected и выполняет следующий обработчик событий.

// Открытие выбранного файла из MRU-списка.
private void MyMruList_FileSelected(string file_name)
{
OpenFile(file_name);
}

Этот код просто вызывает предыдущий метод OpenFile для открытия выбранного файла.

Эта программа не имеет команд Сохранить или Сохранить как, но если бы и имела, то она должна бы была вызывать метод AddFile MruList при каждом сохранении нового или переименованного файла.

Источник: csharphelper.com/blog/2012/04/build-a-most-recently-used-file-mru-list-in-c/

1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (3 оценок, среднее: 4,67 из 5)
Adblock
detector