Click here to Skip to main content
13,289,626 members (58,925 online)
Click here to Skip to main content
Add your own
alternative version


32 bookmarked
Posted 6 Mar 2008

An Application to Keep Track of Your Article Ratings Over Time

, 23 Apr 2009
Rate this:
Please Sign up or sign in to vote.
Collects and records your article ratings plus a couple of new summary ratings
Click for full size screenshot

Click image for full size screenshot

Table of Contents


I like to keep an eye on how my articles are doing, so I wrote a little application to keep track of them. I thought it might be of interest to other authors, so here it is...


This WPF application was written in C# 3.0 using Visual Studio 2008 and requires .NET 3.5.


Please do not abuse this tool by loading lots of members or fetching ratings too often. Chris has kindly allowed me to publish this, so please do not make him regret it by overloading the servers.


If you want to jump right in, this is the section to read. It's not rocket science.

From the User menu, choose Add User. This brings up a dialog box where you can enter a CodeProject member id. This is the number shown on the Who's Who page for the member. Repeat as required.

Press the Get Ratings button.

Save updated data to file.


This is a short description of the metrics recorded by the app, both those calculated by CodeProject and a couple I have added.


This is calculated by CodeProject. I believe each vote is weighted depending on the "Status" of the voter, but I'm not sure about the details. As you know, it is a number between 1 and 5 inclusive.


This is also calculated by CodeProject, but the formula is known. It is:

popularity = rating * log<sub>10</sub>( number of votes )


This is a new summary metric for each author over all his/her articles. It is basically the average of each article's rating, but weighted by the number of votes for the article. I should point out, therefore, that articles with zero votes do not contribute to the X-Rating metric.

xrating = [ sum over all articles of ( votes * rating ) ] / [ total number of votes ]


This is also a new summary metric for each author. It is based on the formula for each article's popularity.

xpopularity = xrating * log<sub>10</sub>( total number of votes )


To make obvious any changes since you last downloaded, the cells in the grid turn yellow for changed metrics. So you can easily see when someone votes for one of your articles and drill into the grid to find the details.

Using the Application

Get Ratings

The "Get Ratings" button works on the currently selected user in the combo box. If "All Users" is selected, it downloads and parses a page for every loaded user. If a particular user is selected, it only gets info for that user.

If you collect your ratings every day or so, you will soon build up a history of statistics showing how your articles are being received over time.


There are five views. The "All Authors" view lists all the summary ratings for all the authors in a file. Then there are two pairs of views. The first pair are the "Totals" and "History" views. These show the summary ratings for a particular author over time and the ratings on a particular date. The second pair are "Articles" and "Details". These show the current ratings for a particular author and the collected ratings for a particular article.

You can double click on a data row in the grid, or press the button, to change views. The view toggles between each view in each pair. You can press ctrl-A to select "All Authors" which shows the authors view again.


You can save the data to a file as either a *.xml or *.bob file. The difference is that the *.bob file compresses the XML by using a GZipStream. This compression reduces the file size by a factor of about ten.

There is no "do you want to save your changes" dialog, so don't forget to save your file after updating.


Apart from adding a user, the only edit you can make is to delete a row. Just select a row and press the backspace or delete key. This functions in all views to remove either an author, an article, or a single detail. Of course you always have the choice of reloading your data from file, thus discarding all unsaved changes.

How it Works

Data from CodeProject

All the data is available on the article summary page for each member. The app fetches this page and parses it using RegEx's. This means it is quite fragile and will stop working if Chris changes so much as a space. However, he doesn't do this very often. I have only tweaked the RegEx's a few times during the two years I have been using this.

The RegEx's are in the CodeProject.cs file, if you want to take a look.


When you save to a file, all collected data is persisted. Nothing is discarded. This means that by taking a snapshot every day or so, you can build up a history of ratings. This in turn enables the application to highlight new votes on articles.

The summary details are calculated whenever they are required from the article stats, so they always reflect your current data. There is some LINQ fun and games going on in Data.cs, if you're interested.


Xceed have written an excellent grid control for WPF and offer an "Express Edition" for free. At the time of writing, they have just released version 2.0 here [^]. They are another benevolent Canadian company, by the way.

Points of Interest

There are plenty of articles about WPF, so I won't dwell on it here. However, there are a couple of things worth mentioning.


The little circles on the buttons come from a neat data template:

<DataTemplate x:Key="ButtonTemplate">
   <StackPanel Orientation="Horizontal">
           <Binding Path="Width" RelativeSource="{RelativeSource AncestorType=Button}" />

       <Ellipse Width="10" Height="10" Margin="0,0,10,0">
               <RadialGradientBrush GradientOrigin="0.3, 0.3">
                   <GradientStop Offset="0.2" 

                          Color="{StaticResource FloralWhiteColour}" />
                   <GradientStop Offset="1" Color="{StaticResource OrangeColour}" />

       <ContentPresenter Content="{TemplateBinding Content}" />

Hooking Events

Double-clicking a row in the grid swaps views. The obvious way I tried was this:

grid.MouseDoubleClick += ( s, a ) => SwapViews();

Unfortunately this also responds to double clicks in areas like the scroll bars.

So I decided to hook the event at the DataRow level. Luckily, the EventManager static class that you use to register a routed event, also has a method called RegisterClassHandler. This allows you to hook an event on all instances of a class:

   typeof( DataRow ),
   new RoutedEventHandler( ( s, a ) => SwapViews() ) );

Hooking Dependency Properties

If you want to know when a dependency property changes, you can use the DependencyPropertyDescriptor class:

   typeof( DataGridControl ) )
   .AddValueChanged( grid, grid_SelectedItemChanged );


Well, that's all folks. If you like this app, please vote. I'll be watching!


2008 March 06:First published
2009 April 23:Bug fix - code updated


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Nicholas Butler
United Kingdom United Kingdom

I built my first computer, a Sinclair ZX80, on my 11th birthday in 1980.
In 1992, I completed my Computer Science degree and built my first PC.
I discovered C# and .NET 1.0 Beta 1 in late 2000 and loved them immediately.
I have been writing concurrent software professionally, using multi-processor machines, since 1995.

In real life, I have spent 3 years travelling abroad,
I have held a UK Private Pilots Licence for 20 years,
and I am a PADI Divemaster.

I now live near idyllic Bournemouth in England.

If you would like help with multithreading, please contact me via my website:

I can work 'virtually' anywhere!

You may also be interested in...


Comments and Discussions

QuestionBroken? Parse error Pin
Yvan Rodrigues28-Nov-11 12:22
memberYvan Rodrigues28-Nov-11 12:22 
GeneralExcelent Pin
Abhijit Jana14-Jun-09 11:21
mvpAbhijit Jana14-Jun-09 11:21 
Generalvery cool Pin
Donsw20-May-09 17:57
memberDonsw20-May-09 17:57 
GeneralAwesome! Pin
thund3rstruck29-Apr-09 9:07
memberthund3rstruck29-Apr-09 9:07 
GeneralRe: Awesome! Pin
Nick Butler29-Apr-09 9:18
memberNick Butler29-Apr-09 9:18 
Thanks and thanks for your vote - it's my 500th over all my articles Smile | :)


Be excellent to each other Smile | :)

NewsDownloads updated 13 April 2009 Pin
Nick Butler13-Apr-09 7:35
memberNick Butler13-Apr-09 7:35 
GeneralException Pin
NinjaCross8-Apr-09 3:43
memberNinjaCross8-Apr-09 3:43 
GeneralRe: Exception Pin
Nick Butler12-Apr-09 0:44
memberNick Butler12-Apr-09 0:44 
GeneralRe: Exception Pin
NinjaCross12-Apr-09 11:30
memberNinjaCross12-Apr-09 11:30 
GeneralRe: Exception Pin
Nick Butler13-Apr-09 7:45
memberNick Butler13-Apr-09 7:45 
GeneralRe: Exception Pin
NinjaCross14-Apr-09 10:58
memberNinjaCross14-Apr-09 10:58 
AnswerRe: Exception Pin
Nick Butler14-Apr-09 11:54
memberNick Butler14-Apr-09 11:54 
GeneralVery well done Pin
Rajesh R Subramanian9-May-08 5:58
mvpRajesh R Subramanian9-May-08 5:58 
GeneralRe: Very well done Pin
Nick Butler9-May-08 6:05
memberNick Butler9-May-08 6:05 
GeneralProxy support Pin
Ashutosh Bhawasinka6-Mar-08 20:46
memberAshutosh Bhawasinka6-Mar-08 20:46 
GeneralRe: Proxy support Pin
Nick Butler6-Mar-08 22:18
memberNick Butler6-Mar-08 22:18 
GeneralRe: Proxy support Pin
Ashutosh Bhawasinka6-Mar-08 22:31
memberAshutosh Bhawasinka6-Mar-08 22:31 
GeneralRe: Proxy support Pin
Nick Butler7-Mar-08 3:40
memberNick Butler7-Mar-08 3:40 
GeneralNice utility Pin
Bert delaVega6-Mar-08 8:04
memberBert delaVega6-Mar-08 8:04 
GeneralRe: Nice utility Pin
Nick Butler6-Mar-08 8:43
memberNick Butler6-Mar-08 8:43 
GeneralRe: Nice utility Pin
Bert delaVega6-Mar-08 8:58
memberBert delaVega6-Mar-08 8:58 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.171207.1 | Last Updated 23 Apr 2009
Article Copyright 2008 by Nicholas Butler
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid