mix2.gif
 Home   Utilities   Purchase   FAQ   Contact     
 
Shareware Utilities
Freeware Utilities
Miscellaneous
clipchk.gif BPSoftware Blog
clipchk.gif Swansea Police Dispatch Log
clipchk.gif Farmville Table
clipchk.gif Purchase Shareware
clipchk.gif Contact


Sunday, October 25, 2009
FarmVille References Updated

There has recently been a significant number of changes to the popular Facebook game FarmVille. Flowers have been added to the list of crops. Fertilized crops yield additional XP when harvested. Pink cows have wondered onto the farm, fresh out of the strawberry patch, and we can't forget those little turtles that seem to have gotten lost.

Just as changes have been made to the game, so to have changes been made to the FarmVille Reference Tables.

The new items have been added to the list, and the display grid now uses AJAX, which eliminates the need to refresh the entire page when changing sort options (don't forget the multi-column sort). Using the reference tables you can easily see, when things are equated on the hour, that:
  • Asparagus is the most profitable Vegetable yielding 7.63 coins per hour
  • Sugar Cane is the most profitable 8 hour seed yielding 59 coins or 7.38 per hour
  • Black Berries are the top when looking for coins and XP, yielding 6.75 and 0.50 per hour

It is time to go view and sort the chart to see how seeds and items yield for the farmer.

Labels: ,

posted by Brad Prendergast at 5:47:00 PM (0 comments)
Links to this post
Permalink
Wednesday, September 30, 2009
ASP.NET GridView: Multiple Column Sort

The native ASP.NET GridView allows for the sorting of data by setting the Grid's AllowSorting property to True.  With AllowSorting enabled, header row cells contain hyperlinks, which when clicked, sort the GridView.  There are several GridView properties and events available which can be used for the customization of the GridView's sort.

  • The Sort method, defined as Sort ( string sortExpression, SortDirection sortDirection ), sorts the GridView based upon the specified sort expression and direction.
  • The Sorting event occurs when the hyperlink column heading is clicked, but before the GridView has handled the sorting of the data.
  • The Sorted event occurs when the hyperlink column heading is clicked, but after the GridView has sorted the datasource.
  • The RowCreated event occurs when a row is created in the GridView.
  • The SortDirection property gets the sort direction of the column being sorted.
  • The SortExpression property gets the sort expression associated with the column being sorted.


The default sort action of the GridView sorts only by a single column.  Using the available sort related events and properties it is rather easy to create a GridView that can be sorted by multiple columns.  The following example is for a GridView than can be sorted by multiple columns.  In this example the columns are sorted in the order they are clicked by a tri-state function.  Clicking on a column heading will set a columns sort state to be Ascending, Descending or Off.  The columns in the GridView are sorted based upon in which they are click or turned on.  When the sort state of a column is Off it is removed from the sort.

1using System;
2using System.Collections.Generic;
3using System.Web.UI;
4using System.Web.UI.WebControls;
5using System.Data;
6
7/// <summary>
8/// MySortItem is a class that is used to in a List<T> to store the sort columns and thier order
9/// </summary>

10public class MySortItem
11{
12 private string columnname;
13 public string ColumnName
14 {
15 get
16 {
17 return columnname;
18 }

19 set
20 {
21 columnname = value;
22 }

23 }

24 private SortDirection columnsort;
25 public SortDirection ColumnSort
26 {
27 get
28 {
29 return columnsort;
30 }

31 set
32 {
33 columnsort = value;
34 }

35 }

36 public string SortToString( SortDirection cs )
37 {
38 string s = ( cs == SortDirection.Ascending ) ? "asc" : "desc";
39 return s;
40 }

41
42}

43
44public partial class _Default : System.Web.UI.Page
45{
46 DataSet ds = new DataSet ();
47 // List for holding sorted columns, their order and their direction
48 List<MySortItem> sl;
49
50
51 protected void Page_Load( object sender, EventArgs e )
52 {
53 // If the Column Sort List does not exist, create it. the list is stored in a session variable
54 if ( Session["sortitems"] == null )
55 {
56 Session["sortitems"] = new List<MySortItem> ();
57 }

58 sl = (List<MySortItem>) Session["sortitems"];
59
60 if ( !Page.IsPostBack )
61 {
62 // Procedure for binding the datasource with the DataGrid
63 BindDataGrid (GridView1);
64 }

65 }

66
67 /// <summary>
68 /// Called from within the application to Bind the DataGrid to a datasource. in this cases it is the default view of a table.
69 /// </summary>

70 protected void BindDataGrid(GridView gv)
71 {
72 // Read data from an XML file
73 ds.ReadXml ( Server.MapPath ( "~/App_Data/Data.xml" ) );
74
75 // build the sort expression
76 string sortexp = "";
77 for ( int i = 0; i < sl.Count; i++ )
78 {
79 sortexp = ( i == 0 ) ? sl[i].ColumnName + " " + sl[i].SortToString ( sl[i].ColumnSort ) : sortexp + "," + sl[i].ColumnName + " " + sl[i].SortToString ( sl[i].ColumnSort );
80 }

81
82 //Set label text to display the sort expression on the page for the user
83 Label3.Text = sortexp;
84 // set the datasource's table default view to indicate sorting; a datatable could also be used directly. In this example a datasource
85 // was used due to dynmaic XML data loading
86 ds.Tables[0].DefaultView.Sort = sortexp;
87 // set the datagrid's datasource
88 gv.DataSource = ds.Tables[0].DefaultView;
89 gv.DataBind ();
90 }

91
92 /// <summary>
93 /// Assigned to the GridView's PagIndexChanging event. This is used if the GridView allows for paging.
94 /// </summary>
95 /// <param name="sender"></param>
96 /// <param name="e"></param>

97 protected void GridView1_PageIndexChanging( object sender, GridViewPageEventArgs e )
98 {
99 try
100 {
101 if ( sender is GridView )
102 {
103 ( (GridView) sender ).PageIndex = e.NewPageIndex;
104 BindDataGrid (GridView1);
105 e.Cancel = false;
106 }

107 }

108 catch
109 {
110
111 e.Cancel = true;
112 }

113 }

114
115 /// <summary>
116 /// Assigned to the GridView's Sorting event.
117 /// </summary>
118 /// <param name="sender"></param>
119 /// <param name="e"></param>

120 protected void GridView1_Sorting( object sender, GridViewSortEventArgs e )
121 {
122 try
123 {
124 // Scroll through the list and see if the clicked GridView column exists in the sort list.
125 // If there is an entry for the column then change the order or remove the column from the list (tri-state)
126 bool found = false;
127 for ( int i = 0; i < sl.Count; i++ )
128 {
129 if ( sl[i].ColumnName == e.SortExpression.ToString () )
130 {
131 found = true;
132 switch ( sl[i].ColumnSort )
133 {
134 case SortDirection.Descending:
135 sl[i].ColumnSort = SortDirection.Ascending;
136 break;
137 case SortDirection.Ascending:
138 sl.RemoveAt ( i );
139 break;
140 }

141 }

142 }

143 if ( !found )
144 {
145 MySortItem si = new MySortItem ();
146 si.ColumnName = e.SortExpression.ToString ();
147 si.ColumnSort = SortDirection.Descending;
148 sl.Add ( si );
149 }

150
151 BindDataGrid (GridView1);
152 //accept column sort
153 e.Cancel = false;
154 }

155 catch ( Exception )
156 {
157 //error so cancel
158 e.Cancel = true;
159 }

160 }

161
162 /// <summary>
163 /// Assigned to the GridView's RowCreated event.
164 /// </summary>
165 /// <param name="sender"></param>
166 /// <param name="e"></param>

167 protected void GridView1_RowCreated( object sender, GridViewRowEventArgs e )
168 {
169 // add images to the column header to indicate sort of each column
170 if ( e.Row.RowType == DataControlRowType.Header )
171 {
172 foreach ( TableCell tc in e.Row.Cells )
173 {
174 if ( tc.HasControls () )
175 {
176 // search for the header link
177 LinkButton lnk = (LinkButton) tc.Controls[0];
178 if ( ( lnk != null ) & ( sl != null ) )
179 {
180 // Get the position of the column in the List<t>
181 int i = sl.FindIndex ( delegate ( MySortItem s )
182 {
183 return s.ColumnName == lnk.CommandArgument;
184 }
);
185 // if the column is found in the list
186 if ( i >= 0 )
187 {
188 System.Web.UI.WebControls.Image img = new System.Web.UI.WebControls.Image ();
189 //set the appropriate image
190 img.ImageUrl = "~/images/" + ( sl[i].ColumnSort == SortDirection.Ascending ? "asc" : "desc" ) + ".gif";
191 // add space and the sort image to header
192 if ( sl[i].ColumnName == lnk.CommandArgument )
193 {
194 tc.Controls.Add ( new LiteralControl ( " " ) );
195 tc.Controls.Add ( img );
196 }

197 }

198 }

199 }

200 }

201 }

202 }

203}

This is all it takes to have an ASP.NET GridView that can be sorted by multiple columns.

Labels: , ,

posted by Brad Prendergast at 6:19:00 AM (1 comments)
Links to this post
Permalink
Saturday, September 19, 2009
Update a control on a Master Page

Creating a Master Page in Visual Studio makes simplifies the development of ASP.NET websites. Master Page's allow for the creation of consistent and standard layouts (template) for a group of pages or an entire website. ContentPlaceHolders are used to designate where on a page based on a Master Page will have variable content. Sometimes it may be necessary to update a control that is part of the Master Page, rather within the ContentPlaceHolder area. There are several ways to update a control on a Master Page. A page's Master property allows for access to a page’s Master Page content. The following code is one example of how to update a control on a master page. The code would be run from the page based on a Master Page.

Image MasterLogo = (Image) Master.FindControl ( "Logo" );
if ( MasterLogo != null )
{
MasterLogo.ImageUrl
= "~/images/logo.gif";
}

Label MasterLabel
= (Label) Master.FindControl ( "Label1" );
if ( MasterLabel != null )
{
MasterLabel.Text
= "Set from page";
}

Labels: ,

posted by Brad Prendergast at 10:49:00 PM (0 comments)
Links to this post
Permalink
Friday, September 18, 2009
Who's Addicted to Farming?

I have to admit it, I am.....

I am not one that is heavy into games or the whole social networking scene, but I have to say zynga did it right with their FarmVille game that is available for play on FaceBook. FarmVille allows you to grow fruits, vegetables and grains on your very own farm.  You purchase and plant seeds and then after a certain period of time you harvest your crops for money. Each crop ripens at different rates of time. Don't leave your ripe crops unattended for too long or they'll wilt away (the rate at which crops wilt is equal to the time they take to ripen). You are not only limited to harvesting crops, but you can harvest trees and have your very own farm animals. Your FarmVille farm can also be decorated with items that you purchase or gifts from your neighbors.

Point blank, the game is addicting. No body knows why, or how, such a simple game can be so time-consuming. Finally everyone, from children to grown adults, can get that chance to live life in the old days. Unlike other simple games, this role-playing simulation is fun overtime instead of just one session. Once you've got a neighbor, that's where the fun begins. Not only can you compete against them in terms of experience level, you can also bring it to a cosmetic level. Whose farm looks the best? Who's the better, more experienced farmer? This is where the game begins to resemble a drug. You'll literally find yourself cutting time out of your day just to plant more crops!

I have created some reference tables for those of you that are also addicted to farming.  If you would like to see any additional information on the page please let me know.

Check out the FarmVille Reference Tables page.

Labels: ,

posted by Brad Prendergast at 11:06:00 PM (3 comments)
Links to this post
Permalink
Saturday, August 22, 2009
iPhoto: Find those unnamed faces

This post marks yet another first. This is the first time that I will post something regarding Apple software. A few months ago I decided to try my luck with a Mac computer. I have not abandoned Windows or Windows development. I have broadened my horizons a bit to now include additional development. With that being said and with the quality of the Mac and great software such as Parallels my PC days are extinct.


iPhoto is a photo management software that comes with Mac OS X. One of the nice features, of which there are several, of this software is its facial recognition capabilities. One of the first things I did when I started using the new Mac was import all of my digital photos into iPhoto. As the pictures were importing, iPhoto churned as it tried to identify the faces in each photo. Once it was complete, I spent some time reviewing each photo to verify the faces that were identified. I had made corrections where necessary. Among the faces in the photos were those that iPhoto couldn't recognize; the 'unnamed' faces.


According to the documentation, iPhoto is supposed to learn from the faces that it has properly identified and any faces that are manually identified. What about the faces that it can't identify and are marked 'unnamed'? I was going through each of my photos, which was a daunting task, and seeing if there were any unnamed faces on them. With several thousand photos, this turns out to be quite a chore. Well, it was quite a chore until I recognized the Smart Albums feature of iPhoto.


Smart Albums allow you to specify photo criteria for it to be included into the album. This 'automatic' album creations saves a lot of time by dynamically creating albums for you (no more drag and drop although you can create those types of albums too). One of the criteria that you can identify is 'faces'. This makes finding those 'unnamed' faces a lot easier than scrolling one by one through each photo. Place the following condition on a smart album and all those unnamed photos will be in the album: Face is unnamed. That is it. Nice and simple. The neat thing is that after all of the unnamed faces have been identified or removed from the photos they will no longer appear in the Album.



iPhoto also allows for the tagging of a photos location (place). This is another way photos can be grouped or even better, selected from the location on a map. Just as a smart album can assist in the identification of photos that contained unnamed faces, a smart album condition can be set to display photos that do not have a location set. Place the following condition in a smart album to see the photos that do not have a location set: 'Place does not contain '. That's it. Nice and simple.

Labels: , ,

posted by Brad Prendergast at 2:55:00 PM (2 comments)
Links to this post
Permalink
Recent Posts


Archives