Introduction
Task Manager is a tool for managing your daily tasks/To-Do list. You can easily manage your tasks using some exciting Windows 7 features. Task manager provides a functionality to set the task title, detail, start date, end date, priority, color tag and flag etc.
Window 7 provides a very nice and managed task bar as compared to the previous versions of Windows. So, I used some new features like JumpList, TabbedThumbnail etc., introduced by Windows 7 in this application. With the help of these new features, Task Manager is a more interactive application. This article will explain how to use these features in the application and will also give teach you to use the ComboBox
and DataGridView
in an advanced manner.
Task Manager also has a separate version for those who do not have Windows 7.
Jump List
Task Manager provides an easy way to view/edit tasks using the Windows 7 jump list. You can easily set your jump list view using the Settings window of the Task Manager.
The Settings window provides you three ways to group your jump list, by Priority, Color Category, or Flag.
It is very easy to manage the Jump list using the Windows API Code Pack. Call the JumpList.CreateJumpList()
method to create a jump list for your application.
private JumpList _jumpList;
private void InitTaskJumpList()
{
_jumpList = JumpList.CreateJumpList();
}
Here is an example to create a jump list for the color category. Create the JumpListCustomCategory
object and add it to the jump list object.
private void ShowJumpListByColorCategory(IQueryable<task> tasks)
{
string[] colorCategories = Enum.GetNames(typeof(TaskCategory));
foreach (string catName in colorCategories)
{
IQueryable<Task> colorTask = tasks.Where(t => t.ColorCategory == catName);
if (colorTask.Count() > 0)
{
JumpListCustomCategory customList = new JumpListCustomCategory(catName);
_jumpList.AddCustomCategories(customList);
foreach (Task task in colorTask)
{
string imagePath = "Resources\\" + catName + "_Category.ico";
AddTask(customList, task.Title, task.TaskID.ToString(), imagePath);
}
}
}
}
Add JumpListLink
to the JumpListCustomCategory
collection using the AddJumpListItems()
method, for creating a jump list link.
private void AddTask(JumpListCustomCategory customCategory,
string text, string argument, string imagePath)
{
string path = Path.GetDirectoryName(Application.ExecutablePath);
JumpListLink jumpListLink =
new JumpListLink(Assembly.GetExecutingAssembly().Location, text);
jumpListLink.Arguments = argument;
jumpListLink.IconReference =
new IconReference(Path.Combine(path, imagePath), 0);
customCategory.AddJumpListItems(jumpListLink);
}
JumpListLink
gets the path of the application executable and its open windows on each click. But Task Manager opens an edit task window of the same application on a link click. You can achieve this functionality using a Mutex
class. Mutex
is used in a multi threaded environment for synchronization mechanisms to ensure that only one thread at a time uses a resource. The SingleInstanceChecker
class checks the running instance of the application.
using (SingleInstanceChecker singleInstance =
new SingleInstanceChecker("TaskManager"))
{
if (!singleInstance.IsSingle)
{
HandleJumpListCommand();
}
else
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
TaskManagerMainForm taskManagerMainForm = new TaskManagerMainForm();
Application.Run(taskManagerMainForm);
}
}
If SingleInstanceChecker
sets IsSingle
to false
, it means the application is already running; handle it using the HandleJumpListCommand()
method. If this event is because of a jump list item, then this method sends a window message to the TaskManagerMainForm
form. TaskManagerMainForm
handles this message by overriding the WndProc
method to handle window messages.
protected override void WndProc(ref Message m)
{
if (m.Msg == WindowMessageHelper.JumplistEvent)
{
int taskID = m.WParam.ToInt32();
OpenAddNewTaskForm(taskID);
}
base.WndProc(ref m);
}
Tabbed Thumbnail
You can easily navigate your incomplete tasks using Tabbed Thumbnail of Windows 7. The Task Manager provides allows you to move forward and back your tasks using the Thumbnail, and you can also edit/view your task details using an Edit button.
The Windows 7 API Code Pack also provides you an easy way to add Tabbed Thumbnail Preview. Just create a TabbedThumbnail
object and add it using the TaskbarManager.Instance.TabbedThumbnail.AddThumbnailPreview()
method. You can also add buttons in it by using the ThumbnailToolbarButton
class. Create an object of this class and add it to the thumbnail using the TaskbarManager.Instance.ThumbnailToolbars.AddButtons()
method. Register the click event of the button for the appropriate action on button click.
private void InitializeThumbnail()
{
if (!HasThumbnailControl(_controlToShow))
{
_btnBack = new ThumbnailToolbarButton(Properties.Resources.Back,
"Previous Task");
_btnBack.Click +=
new EventHandler<thumbnailbuttonclickedeventargs>(_btnBack_Click);
_btnForward = new ThumbnailToolbarButton(Properties.Resources.Forward,
"Next Task");
_btnForward.Click += new
EventHandler<ThumbnailButtonClickedEventArgs>(_btnForward_Click);
_btnEdit = new ThumbnailToolbarButton(
Properties.Resources.edit_Icon, "Edit Task");
_btnEdit.Click += new
EventHandler<ThumbnailButtonClickedEventArgs>(_btnEdit_Click);
TabbedThumbnail thumbnail =
new TabbedThumbnail(_parentHandle, _controlToShow);
thumbnail.DisplayFrameAroundBitmap = true;
thumbnail.SetWindowIcon(Properties.Resources.Task_manager);
thumbnail.Title = "Task Manager";
thumbnail.Tooltip = "Task Manager";
thumbnail.TabbedThumbnailClosed += new
EventHandler<TabbedThumbnailEventArgs>(
thumbnail_TabbedThumbnailClosed);
thumbnail.TabbedThumbnailActivated +=
new EventHandler<TabbedThumbnailEventArgs>(
thumbnail_TabbedThumbnailActivated);
TaskbarManager.Instance.ThumbnailToolbars.AddButtons(
_controlToShow.Handle, _btnBack, _btnForward, _btnEdit);
TaskbarManager.Instance.TabbedThumbnail.AddThumbnailPreview(thumbnail);
TaskbarManager.Instance.TabbedThumbnail.SetActiveTab(_controlToShow);
SetThumbnail();
}
}
The SetThumbnail()
method sets the preview image of the current task. It sets the image using the SetImage()
method.
private void SetThumbnail()
{
TabbedThumbnail preview =
TaskbarManager.Instance.TabbedThumbnail.GetThumbnailPreview(_controlToShow);
if (preview != null)
{
Task task = null;
string toolTip = "Task Manager";
if (_taskList.Count > _selectedIndex)
{
task = _taskList[_selectedIndex];
toolTip = task.Title;
}
_controlToShow.LoadTaskData(task);
preview.Tooltip = toolTip;
Bitmap bitmap = new Bitmap(_controlToShow.Width, _controlToShow.Height);
bitmap = _controlToShow.Image;
preview.SetImage(bitmap);
TaskbarManager.Instance.TabbedThumbnail.SetActiveTab(_controlToShow);
}
}
Progress Bar
The Task Manager also shows the task completed percentage in a progress bar using the Windows 7 Code Pack feature. You can easily set the value of the progress bar.
public static void SetProgressValue(int value)
{
TaskbarProgressBarState state = TaskbarProgressBarState.Normal;
TaskbarManager.Instance.SetProgressState(state);
TaskbarManager.Instance.SetProgressValue(value, 100);
}
Overlay Icon
Icon overlay is the best feature of Windows 7. You can easily see the state of an application with just one look at the task bar. Task Manager also shows two icons on the task bar: one for error and another for confirmation/question.
public static void SetTaskBarIcon(Icon icon)
{
TaskbarManager.Instance.SetOverlayIcon(icon, "icon");
}
Gantt Chart
You can also see the Gantt view of your tasks in the Task Manager. This Gantt chart shows the day view only. The Gantt chart grid shows weekend days (Saturday, Sunday) cells in gray color and shows a green line for current day cells. You can see the busy days with a red bar and it also shows the tooltip with task detail on mouse over on a busy cell.
The GanttChart
class is inherited from DataGridView
because the Gantt chart view is like a grid. The GanttChart
class overrides some methods of DataGridview
to change the default behavior.
protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e)
{
if (e.ColumnIndex < 0)
{
DrawCellColor(e.Graphics, e.CellBounds, Color.SteelBlue, Color.Black);
e.PaintContent(e.CellBounds);
}
else if (e.RowIndex < 0 && e.ColumnIndex >= 0)
{
DrawDayHeaderCell(e);
}
else
{
DrawDataCell(e);
}
e.Handled = true;
}
The OnCellPainting
method executes for each cell drawing, and overrides the cell draw method according to its data and type. If the cell is a header, then it draws the day header, and if the cell is data, then the cell is drawn according to its data. The OnPaint
method handles the drawing of the year header.
protected override void OnPaint(PaintEventArgs e)
{
DrawYearTopHeader(e.Graphics);
base.OnPaint(e);
}
The OnPaint
method simply draws the year header and calls the base class OnPaint(e)
method.
Image in Combo Box
The Task Manager show images in combo boxes for priority, color category, and Flag. .NET provides an easy way to add images in a combo box. Here is the code sample of a priority combo box:
public static void BindTaskPriorityCombo(ComboBox priorityCombo, bool addEmpty)
{
priorityCombo.DrawMode = DrawMode.OwnerDrawVariable;
priorityCombo.DrawItem += new DrawItemEventHandler(priorityCombo_DrawItem);
priorityCombo.Items.Clear();
if (addEmpty)
{
priorityCombo.Items.Add("");
}
foreach (TaskPriority priority in Enum.GetValues(typeof(TaskPriority)))
{
priorityCombo.Items.Add(priority);
}
}
static void priorityCombo_DrawItem(object sender, DrawItemEventArgs e)
{
if (e.Index >= 0)
{
ComboBox cmbPriority = sender as ComboBox;
string text = cmbPriority.Items[e.Index].ToString();
e.DrawBackground();
if (text.Length > 0)
{
TaskPriority priority =
(TaskPriority)Enum.Parse(typeof(TaskPriority), text);
Image img = GetTaskPriorityImage(priority);
if (img != null)
{
e.Graphics.DrawImage(img, e.Bounds.X, e.Bounds.Y, 15, 15);
}
}
e.Graphics.DrawString(text, cmbPriority.Font,
System.Drawing.Brushes.Black,
new RectangleF(e.Bounds.X + 15, e.Bounds.Y,
e.Bounds.Width, e.Bounds.Height));
e.DrawFocusRectangle();
}
}
For adding an image to a combo box, you need to set the DrawMode
of the combobox: DrawMode = DrawMode.OwnerDrawVariable
. Then, you need to override the DrawItem
event of the combo box where you can draw the item as you want.