Saturday, November 17, 2012

Price Is Right

This past summer, a friend of mine tipped me off to Coursera, a site where many big name universities are offering free online courses to large numbers of students. I had really hoped to take a traditional university course in the fall, but was unable to, due to my schedule, and decided to give one of Coursera's offerings a try. I have to admit that I was pleasantly surprised by how much I got out of the course.

After reviewing the directory of available courses, I decided to take Stanford's Human Computer Interaction, which is a course on software design. For those interested in software development, there are a good variety of courses to choose from. Even if you're not, there are money other topics that are touched on in the 200+ courses available.

The assignments proved to be very interesting, and it will be fun to apply some of these techniques to a real world project. To start out, we had to observe three people performing a particular action, determining areas where technology could help them improve their experience. Next, we had to draw up storyboards (similar to a comic strip), demonstrating a scenario in which our proposed technology could be used. After this, we created a prototype using Balsamiq Mockups. Once this was done, we built an interactive version of our prototype. Finally, we sought out three people to test our prototype and identify flaws.

The video lectures were informative as well, but I personally got the most out of the assignments, and would whole-heartedly recommend this class. You can't really beat an offering like this for the price.

The only thing that proved slightly annoying to me was the grading. Due to the size of the course, students grade each others' homework. Each person is responsible for grading the homework of five other people. Some weeks this took a considerable amount of time. Towards the end of the course, the faculty did recognize that this was the case and made adjustments so that a lesser amount of time was needed. One other small annoyance with this method of grading was that I found that other students tended to add requirements that were not outlined in the instructions for grading, due to their own idea of how the assignment should be completed.

In the end, the minor annoyances were not of importance, as the key was the amount of learning that was gained via the assignments. If you have a chance to take a look at one of Coursera's courses, I would certainly recommend it. The friend that pointed me to the site is just wrapping up a course that he is taking as well and sounds like he is equally satisfied with the one that he chose to take.

Wednesday, September 26, 2012

Task Conqueror Launched

As you may have read in my previous posts, I've been working on a small WPF task management application. Version 1.0.0 was just released, and you can view more details at Task Conqueror is a goal-oriented task management application that will help you keep an eye on your goals as you compile your daily task list.

It's been a fun project, and a great learning experience for me. Although I have spent more hours at work with WPF than I did on this project, there was a lot to be learned from building my own application from the ground up. Admittedly, I didn't write everything from scratch. The framework is based on the example given in Josh Smith's article, WPF Apps With The Model-View-ViewModel Design Pattern. If you're not familiar with MVVM, I would definitely recommend that you give it a read.

Saturday, September 8, 2012

Displaying Context Sensitive Help With WPF

I've been working on a small WPF task management app and decided to write a help file for it using HTML Help Workshop. After completing the help file, I wanted to tie my application into the CHM file, displaying the topic relevant for the current window. Strangely, I was not able to find a lot of good examples that tied this approach all together. Apparently, this is not something that people commonly do. Anyway, below is an example of how to pull it off.

Help.ShowHelp(null, "help.chm", "html/active_tasks/search.htm");
The part that was tripping me up was that the third parameter, which is named "keyword", is actually a URL to the page within your help file that you want to display. There's an MSDN article that describes it a little further, although the code example does not make it extremely obvious. Here's the article that finally got me over the hump.

Monday, September 3, 2012

Large Project Mentality

As a software developer, most of the time that I spend working on projects is spent on projects that take months to years to completed. When a project of this size is completed, it leaves me with a great feeling of stisfaction. However, it can be tough when you're bogged down in the middle of such a large project with completion far out on the horizon.

At such a time, it's really nice to take a break with a one day mini project. Not only does such a project reward a person with the satisfaction of a job successfully completed, but it can also provide a much needed change of pace. While a bug fix on a legacy system can serve the purpose, I find it refreshing to do a small project with my hands, such as a carpentry project. Combining the reward of completion with exposure to a different discipline can even serve to boost one's creativity for other projects being worked.

Interestingly, I found out via discussion that some people rarely, if ever, tackle a lengthy project. My wife works in a field where the end product is generally produced in minutes or hours at the most. She will even admit that she has had a tough time completing lengthy projects outside of work, whereas I am constantly taking them on. It makes me wonder if working in a field that deals with lengthy projects makes a person predisposed toward tackling long projects in their spare time.

Sunday, September 2, 2012

Visual Studio 2012 - Three New Features For Everyday Usage

Last week my employer started using Visual Studio 2012. For the most part, I like what I've seen. Although I haven't used it enough to get an idea of all its idiosyncrasies, I have noticed a few new features that will be useful in everyday situations.

One big new feature is the ability to open Visual Studio 2010 solutions without going through a conversion process. In previous versions, you would be forced to convert a solution, meaning that it could no longer be opened in an even earlier version. This scenario would force a whole team to upgrade to the new version of Visual Studio. With 2012, one or two developers can give the new version a shot, while the rest of the team continues to work with Visual Studio 2010.

Another nice new feature is the ability to have multiple tabs on another window on a second monitor. Being able to pull a tab of code over to a second window was a great feature in Visual Studio 2010, making it easy to do a side by side comparison of code. Visual Studio 2012 expands on this by allowing multiple tabs in a second window. This can be useful if you want to explore two separate areas of an application while organizing the source files in separate windows.

A third new feature resolves a previous pet peeve of mine. In Visual Studio 2010, right-clicking on a tab would reveal a context menu that included options for closing the current tab or all other tabs. Strangely, no option existed on the menu to close all tabs, although this was something I often wanted to do. It was nice to see a context menu item added in Visual Studio 2012 to close all tabs.

Tuesday, July 24, 2012

Building Tables In FlowDocuments

Recently I've been working on a WPF task management application. I decided that it would be nice to add some reporting capabilities, but wasn't sure about the best reporting option considering that I am using Visual C# 2010 Express and SQL Server CE 3.5.

At work I had already had some exposure to building documents using the FlowDocument class, so I thought that could serve as a decent reporting mechanism for the simple reports that I was trying to make. After completing the first report using a tabular layout, I realized that my table building code would be pretty much similar for all of the reports. As a result, I factored it out into a common method, which you can see below.

public static Table BuildTable(Dictionary columnDefinitions, List rowRecords)
    Table flowTable = new Table();
    flowTable.CellSpacing = 10;
    flowTable.Background = System.Windows.Media.Brushes.White;

    // Create columns and add them to the table's Columns collection.
    int numberOfColumns = columnDefinitions.Count;
    for (int x = 0; x < numberOfColumns; x++)
        flowTable.Columns.Add(new TableColumn());

    // Create and add an empty TableRowGroup to hold the table's Rows.
    flowTable.RowGroups.Add(new TableRowGroup());

    // Add the header row.
    flowTable.RowGroups[0].Rows.Add(new TableRow());
    TableRow currentRow = flowTable.RowGroups[0].Rows[0];

    // Global formatting for the header row.
    currentRow.FontSize = 18;
    currentRow.FontWeight = FontWeights.Bold;

    // Add cells with content to the second row.
    foreach (string propertyName in columnDefinitions.Keys)
        currentRow.Cells.Add(new TableCell(new Paragraph(new Run(columnDefinitions[propertyName]))));

    int currentRowCount = 1;

    // loop through content and output table rows.
    foreach (T rowRecord in rowRecords)
        flowTable.RowGroups[0].Rows.Add(new TableRow());
        currentRow = flowTable.RowGroups[0].Rows[currentRowCount];
        currentRow.FontSize = 12;
        currentRow.FontWeight = FontWeights.Normal;

        foreach (string propertyName in columnDefinitions.Keys)
            object propertyValue = rowRecord.GetType().GetProperty(propertyName).GetValue(rowRecord, null);
            string convertedValue = propertyValue == null ? "" : propertyValue.ToString();
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run(convertedValue))));


    return flowTable;

The first parameter is a dictionary of property names and the column titles that go with them. The second is a list of the row records used to build the table. Below is some sample code for calling the method.

Dictionary columnDefinitions = new Dictionary()
    {"Name", "Name"},
    {"Rank", "Rank"},
    {"SerialNumber", "Serial Number"}

List activePeople = tData.GetActivePeople();

flowDocument.Blocks.Add(FlowDocumentHelper.BuildTable(columnDefinitions, activePeople));