Click here to Skip to main content
15,884,298 members
Articles / Programming Languages / C#

An Application to Keep Track of Your Article Ratings Over Time

Rate me:
Please Sign up or sign in to vote.
4.79/5 (19 votes)
23 Apr 2009CPOL5 min read 57.8K   1.3K   35   22
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

Introduction

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...

Requirements

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

Caveat

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.

Quickstart

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.

Metrics

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

Rating

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.

Popularity

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

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

X-Rating

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 ]

X-Popularity

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 )

Highlighting

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.

Views

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.

Persistance

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.

Editing

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.

Persistance

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.Wpf.DataGrid

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.

Buttons

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

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

       <Ellipse Width="10" Height="10" Margin="0,0,10,0">
           <Ellipse.Fill>
               <RadialGradientBrush GradientOrigin="0.3, 0.3">
                   <GradientStop Offset="0.2" 
                          Color="{StaticResource FloralWhiteColour}" />
                   <GradientStop Offset="1" Color="{StaticResource OrangeColour}" />
               </RadialGradientBrush>
           </Ellipse.Fill>
       </Ellipse>

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

Hooking Events

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

C#
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:

C#
EventManager.RegisterClassHandler(
   typeof( DataRow ),
   Control.MouseDoubleClickEvent,
   new RoutedEventHandler( ( s, a ) => SwapViews() ) );

Hooking Dependency Properties

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

C#
DependencyPropertyDescriptor.FromProperty(
   DataGridControl.SelectedItemProperty,
   typeof( DataGridControl ) )
   .AddValueChanged( grid, grid_SelectedItemChanged );

Conclusion

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

History

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

License

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


Written By
United Kingdom United Kingdom
I discovered C# and .NET 1.0 Beta 1 in late 2000 and loved them immediately.
I have been writing software professionally in C# ever since

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.

I can work 'virtually' anywhere!

Comments and Discussions

 
GeneralMy vote of 5 Pin
dental implant23-Jul-23 6:19
professionaldental implant23-Jul-23 6:19 
QuestionBroken? Parse error Pin
Yvan Rodrigues28-Nov-11 11:22
professionalYvan Rodrigues28-Nov-11 11:22 
GeneralExcelent Pin
Abhijit Jana14-Jun-09 10:21
professionalAbhijit Jana14-Jun-09 10:21 
Generalvery cool Pin
Donsw20-May-09 16:57
Donsw20-May-09 16:57 
GeneralAwesome! Pin
thund3rstruck29-Apr-09 8:07
thund3rstruck29-Apr-09 8:07 
GeneralRe: Awesome! Pin
Nicholas Butler29-Apr-09 8:18
sitebuilderNicholas Butler29-Apr-09 8:18 
NewsDownloads updated 13 April 2009 Pin
Nicholas Butler13-Apr-09 6:35
sitebuilderNicholas Butler13-Apr-09 6:35 
GeneralException Pin
NinjaCross8-Apr-09 2:43
NinjaCross8-Apr-09 2:43 
GeneralRe: Exception Pin
Nicholas Butler11-Apr-09 23:44
sitebuilderNicholas Butler11-Apr-09 23:44 
GeneralRe: Exception Pin
NinjaCross12-Apr-09 10:30
NinjaCross12-Apr-09 10:30 
Thankyou for your effort, I'll try them asap Smile | :)

--
NinjaCross
www.ninjacross.com

GeneralRe: Exception Pin
Nicholas Butler13-Apr-09 6:45
sitebuilderNicholas Butler13-Apr-09 6:45 
GeneralRe: Exception Pin
NinjaCross14-Apr-09 9:58
NinjaCross14-Apr-09 9:58 
AnswerRe: Exception Pin
Nicholas Butler14-Apr-09 10:54
sitebuilderNicholas Butler14-Apr-09 10:54 
GeneralVery well done Pin
Rajesh R Subramanian9-May-08 4:58
professionalRajesh R Subramanian9-May-08 4:58 
GeneralRe: Very well done Pin
Nicholas Butler9-May-08 5:05
sitebuilderNicholas Butler9-May-08 5:05 
GeneralProxy support Pin
Ashutosh Bhawasinka6-Mar-08 19:46
Ashutosh Bhawasinka6-Mar-08 19:46 
GeneralRe: Proxy support Pin
Nicholas Butler6-Mar-08 21:18
sitebuilderNicholas Butler6-Mar-08 21:18 
GeneralRe: Proxy support Pin
Ashutosh Bhawasinka6-Mar-08 21:31
Ashutosh Bhawasinka6-Mar-08 21:31 
GeneralRe: Proxy support Pin
Nicholas Butler7-Mar-08 2:40
sitebuilderNicholas Butler7-Mar-08 2:40 
GeneralNice utility Pin
Bert delaVega6-Mar-08 7:04
Bert delaVega6-Mar-08 7:04 
GeneralRe: Nice utility Pin
Nicholas Butler6-Mar-08 7:43
sitebuilderNicholas Butler6-Mar-08 7:43 
GeneralRe: Nice utility Pin
Bert delaVega6-Mar-08 7:58
Bert delaVega6-Mar-08 7: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.