Сайт разработчика Александр Климова

/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000

Менеджер задач

Бросить курить. Заняться зарядкой. Проводить больше времени с семьей. Эти задачи ставят люди во всем мире перед Новым годом. Почему бы не написать программульку, которая будет хранить ваши задачи и контролировать их выполнение. Постановка подобных задач с указанием даты, когда надо решить проблему поможет расставить приоритеты и подтолкнуть к решительным действиям.

Итак, наше приложение будет представлять собой список задач, хранящих пожелания на Новый год или другие задачи. Интерфейс у программы будет простым. Главная задача приложения – это предупредить пользователя, что срок задачи наступил. Предупреждение будет выводиться при помощи специальной подсказки в области уведомлений, а сама программа будет вызываться по значку в этой области. Двойной щелчок на значке позволяет выводить диалоговое окно для управления задачами (добавить, изменить или удалить). Правый щелчок мыши вызывает меню для закрытия приложения.

В диалоговом окне будет использоваться элемент управления CheckedListBox для показа задач. Этот элемент состоит из списка элементов как в обычном элементе управления ListBox, но при этом у каждого элемента списка присутствует элемент CheckBox. Это решение позволяет легко использовать возможности доступен/не доступен или выбран/не выбран для элементов списка. Флажок в списке позволит нам отмечать выполненные задачи. Элемент имеет типичное событие ListIndexChanged и другие события, связанные с мышью, а также событие ItemCheck. Задачи легко добавить в список при помощи кнопки Add, а удалять или редактировать при помощи кнопок Remove или Edit.

Когда задача добавляется или редактируется, появляется диалоговое окно Task Details. Эта форма содержит элементы для названия задачи, времени и состояния. Диалоговое окно выводится из основной формы при помощи метода ShowDialog:


int rowId = tasksCheckedListBox.SelectedIndex;
TasksDataSet.TasksRow row = ds.Tasks[rowId];

details.CurrentRow = row;

if (details.ShowDialog() == DialogResult.OK)
{
       UpdateDisplayWithRow(rowId, row);
}

Метод ShowDialog возвращает член перечисления DialogResult. Когда вы создаете кнопки для этого диалога, вы можете установить свойство DialogResult в такие значения как OK, Yes, или Cancel. Диалог Form Details имеет кнопки OK и Cancel.


private void dialogOKButton_Click(object sender, EventArgs e)
{
   bool newRow = false;

    if (row == null)
    {
         row = table.NewTasksRow();
         newRow = true;
    }

    row.TaskTitle = titleTextBox.Text;
    row.TaskDueDate = taskDateTimePicker.Value.Date;
    row.TaskComplete = taskCheckBox.Checked;

    if (newRow)
    {
         table.AddTasksRow(row);
    }
}

Чтобы удалить кнопки в правом углу формы, нужно установить свойство ControlBox в значение False.

Когда задача будет заведена в приложение, данные при помощи типа DataSet сохраняются в файл, используя возможности XML. Заключительная часть – вывести предупреждение, когда наступит запланированное время. Для этого используется элемент Timer со свойством Interval равным 60000. Это означает, что событие Tick посылается таймером раз в минуту.

Каждый раз, когда срабатывает событие Tick, обработчик события проходит через таблицу задач в поисках записи, у которой заданное время совпадает с текущим временем или уже прошло. Если такая задача обнаружена, ее необходимо показать пользователю. Заголовок и дата, добавленные в задачу, выводятся в специальной подсказке. Так как могут быть несколько задач для вывода, то использование объекта String не эффективно. В таких случаях лучше использовать объект StringBuilder.


// StringBuilder is more efficient than string concatentation
StringBuilder buffer = new StringBuilder();

// Iterate over each task in the DataSet
foreach (TasksDataSet.TasksRow row in ds.Tasks)
{
   // Compare date and completed flag
   if ((DateTime.Now.Date > row.TaskDueDate) && !row.TaskComplete)
   {
       buffer.Append(row.TaskTitle).Append(", Due: ");
       buffer.AppendFormat("{0:d}", row.TaskDueDate).Append('\n');
   }
}

Когда задачи будут добавлены в буфер, их можно будет вывести на экран. Убедившись, что буфер имеет хотя бы один символ, мы выводим задачу. Метод ShowBalloonTip значка области уведомлений показывает специальное окно подсказки, знакомое вам по многим системным приложениям.


// If the buffer is not empty, there is at least one
// task to display
if (buffer.Length > 0)
{
     // Display an Info balloon tip for 8 seconds
     appNotifyIcon.ShowBalloonTip(8000, 
                              "Coding 4 Fun - Task Manager", 
                              buffer.ToString(), ToolTipIcon.Info);
}

Подсказка содержит заголовок, сообщение и значок, схожий со значками в MessageBox.

Так как приложение не имеет пользовательского интерфейса, его нужно как-то по особенному разработать. Обычный вариант с использованием шаблона Windows Form не совсем подходит. Воспользуемся классом Program, содержащим вход в программу – метод Main. В этом методе создадим основную форму и запустим приложение при помощи метода Run объекта Application. Также сделаем так, чтобы у нас не запускалась вторая копия программы, так как в этом нет необходимости. Для этого подойдет класс Mutex в пространстве имен System.Threading. Создаем мьютекс, запрашивающий владельца. Если мы владельцы программы, то используем эту ситуацию.


bool onlyInstance;
Mutex mtx = new Mutex(true, "C4F:TaskManager", out onlyInstance);

// If no other process owns the mutex, this is the
// only instance of the application.
if (onlyInstance)
{

   // Create the main form, then start the
   // application.  If the form is closed,
   // the application continues to run.
   TaskManagerForm mf = new TaskManagerForm();

   Application.Run();
}
else
{
   MessageBox.Show(
      "An instance is already running",
      "Coding 4 Fun - Task Manager ",
      MessageBoxButtons.OK, MessageBoxIcon.Stop);
}

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

Скачать пример

Перевод: Василий Котов

Реклама